home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / atlctl.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  74.3 KB  |  2,732 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10.  
  11. #ifndef __ATLCTL_H__
  12. #define __ATLCTL_H__
  13.  
  14. #ifndef __cplusplus
  15.     #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #include "atlwin.h"
  19. #include <objsafe.h>
  20. #include <urlmon.h>
  21.  
  22. #if !defined(BCC32_COMPAT)
  23. #pragma comment(lib, "gdi32.lib")
  24. #pragma comment(lib, "urlmon.lib")
  25. #endif
  26.  
  27. ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix);
  28. ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric);
  29. ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd);
  30.  
  31. // Include GUIDs for the new stock property dialogs contained in the dll MSStkProp.DLL
  32. #include "msstkppg.h"
  33. #define CLSID_MSStockFont CLSID_StockFontPage
  34. #define CLSID_MSStockColor CLSID_StockColorPage
  35. #define CLSID_MSStockPicture CLSID_StockPicturePage
  36.  
  37. #ifndef ATL_NO_NAMESPACE
  38. namespace ATL
  39. {
  40. #endif
  41.  
  42. #pragma pack(push, _ATL_PACKING)
  43.  
  44. // Forward declarations
  45. //
  46. class ATL_NO_VTABLE CComControlBase;
  47. template <class T> class CComControl;
  48. class CComDispatchDriver;
  49.  
  50. struct ATL_PROPMAP_ENTRY
  51. {
  52.     LPCOLESTR szDesc;
  53.     DISPID dispid;
  54.     const CLSID* pclsidPropPage;
  55.     const IID* piidDispatch;
  56.  
  57. };
  58.  
  59. struct ATL_DRAWINFO
  60. {
  61.     UINT cbSize;
  62.     DWORD dwDrawAspect;
  63.     LONG lindex;
  64.     DVTARGETDEVICE* ptd;
  65.     HDC hicTargetDev;
  66.     HDC hdcDraw;
  67.     LPCRECTL prcBounds; //Rectangle in which to draw
  68.     LPCRECTL prcWBounds; //WindowOrg and Ext if metafile
  69.     BOOL bOptimize;
  70.     BOOL bZoomed;
  71.     BOOL bRectInHimetric;
  72.     SIZEL ZoomNum;      //ZoomX = ZoomNum.cx/ZoomNum.cy
  73.     SIZEL ZoomDen;
  74. };
  75.  
  76. //////////////////////////////////////////////////////////////////////////////
  77. // CComDispatchDriver / Specialization of CComQIPtr<IDispatch, IID_IDispatch>
  78. class CComDispatchDriver
  79. {
  80. public:
  81.     CComDispatchDriver()
  82.     {
  83.         p = NULL;
  84.     }
  85.     CComDispatchDriver(IDispatch* lp)
  86.     {
  87.         if ((p = lp) != NULL)
  88.             p->AddRef();
  89.     }
  90.     CComDispatchDriver(IUnknown* lp)
  91.     {
  92.         p=NULL;
  93.         if (lp != NULL)
  94.             lp->QueryInterface(IID_IDispatch, (void **)&p);
  95.     }
  96.     ~CComDispatchDriver() { if (p) p->Release(); }
  97.     void Release() {if (p) p->Release(); p=NULL;}
  98.     operator IDispatch*() {return p;}
  99.     IDispatch& operator*() {_ASSERTE(p!=NULL); return *p; }
  100.     IDispatch** operator&() {_ASSERTE(p==NULL); return &p; }
  101.     IDispatch* operator->() {_ASSERTE(p!=NULL); return p; }
  102.     IDispatch* operator=(IDispatch* lp){return (IDispatch*)AtlComPtrAssign((IUnknown**)&p, lp);}
  103.     IDispatch* operator=(IUnknown* lp)
  104.     {
  105.         return (IDispatch*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IDispatch);
  106.     }
  107.     BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  108.  
  109.     HRESULT GetProperty(DISPID dwDispID, VARIANT* pVar)
  110.     {
  111.         _ASSERTE(p);
  112.         return GetProperty(p, dwDispID, pVar);
  113.     }
  114.     HRESULT PutProperty(DISPID dwDispID, VARIANT* pVar)
  115.     {
  116.         _ASSERTE(p);
  117.         return PutProperty(p, dwDispID, pVar);
  118.     }
  119.  
  120.     static HRESULT GetProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar);
  121.     static HRESULT PutProperty(IDispatch* pDisp, DISPID dwDispID, VARIANT* pVar);
  122.     IDispatch* p;
  123. };
  124.  
  125. //////////////////////////////////////////////////////////////////////////////
  126. // CFirePropNotifyEvent
  127. class CFirePropNotifyEvent
  128. {
  129. public:
  130.     static HRESULT FireOnRequestEdit(IUnknown* pUnk, DISPID dispID);
  131.     static HRESULT FireOnChanged(IUnknown* pUnk, DISPID dispID);
  132. };
  133.  
  134.  
  135. //////////////////////////////////////////////////////////////////////////////
  136. // CFakeFirePropNotifyEvent
  137. class CFakeFirePropNotifyEvent
  138. {
  139. public:
  140.     static HRESULT FireOnRequestEdit(IUnknown* /*pUnk*/, DISPID /*dispID*/)
  141.     {
  142.         return S_OK;
  143.     }
  144.     static HRESULT FireOnChanged(IUnknown* /*pUnk*/, DISPID /*dispID*/)
  145.     {
  146.         return S_OK;
  147.     }
  148. };
  149.  
  150.  
  151. typedef CFakeFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  152.  
  153. //////////////////////////////////////////////////////////////////////////////
  154. // CComControl
  155. class ATL_NO_VTABLE CComControlBase
  156. {
  157. public:
  158.     CComControlBase(HWND& h) : m_hWndCD(h)
  159.     {
  160.         memset(this, 0, sizeof(CComControlBase));
  161.         m_phWndCD = &h;
  162.         m_sizeExtent.cx = 2*2540;
  163.         m_sizeExtent.cy = 2*2540;
  164.         m_sizeNatural = m_sizeExtent;
  165.     }
  166.     ~CComControlBase()
  167.     {
  168.         if (m_hWndCD != NULL)
  169.             ::DestroyWindow(m_hWndCD);
  170.         ATLTRACE(_T("Control Destroyed\n"));
  171.     }
  172.  
  173. // methods
  174. public:
  175.     // Control helper functions can go here
  176.     // non-virtuals only please
  177.     void SetDirty(BOOL bDirty)
  178.     {
  179.         m_bRequiresSave = bDirty;
  180.     }
  181.     BOOL GetDirty()
  182.     {
  183.         return m_bRequiresSave ? TRUE : FALSE;
  184.     }
  185.     void GetZoomInfo(ATL_DRAWINFO& di);
  186.     HRESULT SendOnRename(IMoniker *pmk)
  187.     {
  188.         HRESULT hRes = S_OK;
  189.         if (m_spOleAdviseHolder)
  190.             hRes = m_spOleAdviseHolder->SendOnRename(pmk);
  191.         return hRes;
  192.     }
  193.     HRESULT SendOnSave()
  194.     {
  195.         HRESULT hRes = S_OK;
  196.         if (m_spOleAdviseHolder)
  197.             hRes = m_spOleAdviseHolder->SendOnSave();
  198.         return hRes;
  199.     }
  200.     HRESULT SendOnClose()
  201.     {
  202.         HRESULT hRes = S_OK;
  203.         if (m_spOleAdviseHolder)
  204.             hRes = m_spOleAdviseHolder->SendOnClose();
  205.         return hRes;
  206.     }
  207.     HRESULT SendOnDataChange(DWORD advf = 0);
  208.     HRESULT SendOnViewChange(DWORD dwAspect, LONG lindex = -1)
  209.     {
  210.         if (m_spAdviseSink)
  211.             m_spAdviseSink->OnViewChange(dwAspect, lindex);
  212.         return S_OK;
  213.     }
  214.     LRESULT OnSetFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  215.     {
  216.         CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  217.         if (m_bInPlaceActive && spSite)
  218.             spSite->OnFocus(TRUE);
  219.         return 0;
  220.     }
  221.  
  222.     LRESULT OnKillFocus(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  223.     {
  224.         CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  225.         if (m_bInPlaceActive && spSite)
  226.             spSite->OnFocus(FALSE);
  227.         return 0;
  228.     }
  229.     LRESULT OnGetDlgCode(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* bHandled */)
  230.     {
  231.         return 0;
  232.     }
  233.  
  234.     HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var)
  235.     {
  236.         HRESULT hRes = E_FAIL;
  237.         if (m_spAmbientDispatch.p != NULL)
  238.             hRes = m_spAmbientDispatch.GetProperty(dispid, &var);
  239.         return hRes;
  240.     }
  241.     HRESULT GetAmbientAppearance(short& nAppearance)
  242.     {
  243.         CComVariant var;
  244.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_APPEARANCE, var);
  245.         _ASSERTE(var.vt == VT_I2 || FAILED(hRes));
  246.         nAppearance = var.iVal;
  247.         return hRes;
  248.     }
  249.     HRESULT GetAmbientBackColor(OLE_COLOR& BackColor)
  250.     {
  251.         CComVariant var;
  252.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_BACKCOLOR, var);
  253.         _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  254.         BackColor = var.lVal;
  255.         return hRes;
  256.     }
  257.     HRESULT GetAmbientDisplayName(BSTR& bstrDiaplayName)
  258.     {
  259.         CComVariant var;
  260.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYNAME, var);
  261.         _ASSERTE(var.vt == VT_BSTR || FAILED(hRes));
  262.         bstrDiaplayName = var.bstrVal;
  263.         return hRes;
  264.     }
  265.     HRESULT GetAmbientFont(IFont** ppFont)
  266.     {
  267.         // caller MUST Release the font!
  268.         if (ppFont == NULL)
  269.             return E_POINTER;
  270.         CComVariant var;
  271.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  272.         _ASSERTE((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  273.         if (SUCCEEDED(hRes) && var.pdispVal)
  274.         {
  275.             if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  276.                 hRes = var.pdispVal->QueryInterface(IID_IFont, (void**)ppFont);
  277.             else
  278.                 hRes = DISP_E_BADVARTYPE;
  279.         }
  280.         return hRes;
  281.     }
  282.     HRESULT GetAmbientForeColor(OLE_COLOR& ForeColor)
  283.     {
  284.         CComVariant var;
  285.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FORECOLOR, var);
  286.         _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  287.         ForeColor = var.lVal;
  288.         return hRes;
  289.     }
  290.     HRESULT GetAmbientLocaleID(LCID& lcid)
  291.     {
  292.         CComVariant var;
  293.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_LOCALEID, var);
  294.         _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  295.         lcid = var.lVal;
  296.         return hRes;
  297.     }
  298.     HRESULT GetAmbientScaleUnits(BSTR& bstrScaleUnits)
  299.     {
  300.         CComVariant var;
  301.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SCALEUNITS, var);
  302.         _ASSERTE(var.vt == VT_BSTR || FAILED(hRes));
  303.         bstrScaleUnits = var.bstrVal;
  304.         return hRes;
  305.     }
  306.     HRESULT GetAmbientTextAlign(short& nTextAlign)
  307.     {
  308.         CComVariant var;
  309.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_TEXTALIGN, var);
  310.         _ASSERTE(var.vt == VT_I2 || FAILED(hRes));
  311.         nTextAlign = var.iVal;
  312.         return hRes;
  313.     }
  314.     HRESULT GetAmbientUserMode(BOOL& bUserMode)
  315.     {
  316.         CComVariant var;
  317.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  318.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  319.         bUserMode = var.boolVal;
  320.         return hRes;
  321.     }
  322.     HRESULT GetAmbientUIDead(BOOL& bUIDead)
  323.     {
  324.         CComVariant var;
  325.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_UIDEAD, var);
  326.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  327.         bUIDead = var.boolVal;
  328.         return hRes;
  329.     }
  330.     HRESULT GetAmbientShowGrabHandles(BOOL& bShowGrabHandles)
  331.     {
  332.         CComVariant var;
  333.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWGRABHANDLES, var);
  334.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  335.         bShowGrabHandles = var.boolVal;
  336.         return hRes;
  337.     }
  338.     HRESULT GetAmbientShowHatching(BOOL& bShowHatching)
  339.     {
  340.         CComVariant var;
  341.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWHATCHING, var);
  342.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  343.         bShowHatching = var.boolVal;
  344.         return hRes;
  345.     }
  346.     HRESULT GetAmbientMessageReflect(BOOL& bMessageReflect)
  347.     {
  348.         CComVariant var;
  349.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, var);
  350.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  351.         bMessageReflect = var.boolVal;
  352.         return hRes;
  353.     }
  354.     HRESULT GetAmbientAutoClip(BOOL& bAutoClip)
  355.     {
  356.         CComVariant var;
  357.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, var);
  358.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  359.         bAutoClip = var.boolVal;
  360.         return hRes;
  361.     }
  362.     HRESULT GetAmbientDisplayAsDefault(BOOL& bDisplaysDefault)
  363.     {
  364.         CComVariant var;
  365.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYASDEFAULT, var);
  366.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  367.         bDisplaysDefault = var.boolVal;
  368.         return hRes;
  369.     }
  370.     HRESULT GetAmbientSupportsMnemonics(BOOL& bSupportMnemonics)
  371.     {
  372.         CComVariant var;
  373.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SUPPORTSMNEMONICS, var);
  374.         _ASSERTE(var.vt == VT_BOOL || FAILED(hRes));
  375.         bSupportMnemonics = var.boolVal;
  376.         return hRes;
  377.     }
  378.     HRESULT GetAmbientPalette(HPALETTE& hPalette)
  379.     {
  380.         CComVariant var;
  381.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_PALETTE, var);
  382.         _ASSERTE(var.vt == VT_I4 || FAILED(hRes));
  383.         hPalette = reinterpret_cast<HPALETTE>(var.lVal);
  384.         return hRes;
  385.     }
  386.  
  387.     BOOL DoesVerbUIActivate(LONG iVerb)
  388.     {
  389.         BOOL b = FALSE;
  390.         switch (iVerb)
  391.         {
  392.             case OLEIVERB_UIACTIVATE:
  393.             case OLEIVERB_PRIMARY:
  394.                 b = TRUE;
  395.                 break;
  396.         }
  397.         // if no ambient dispatch then in old style OLE container
  398.         if (DoesVerbActivate(iVerb) && m_spAmbientDispatch.p == NULL)
  399.             b = TRUE;
  400.         return b;
  401.     }
  402.  
  403.     BOOL DoesVerbActivate(LONG iVerb)
  404.     {
  405.         BOOL b = FALSE;
  406.         switch (iVerb)
  407.         {
  408.             case OLEIVERB_UIACTIVATE:
  409.             case OLEIVERB_PRIMARY:
  410.             case OLEIVERB_SHOW:
  411.             case OLEIVERB_INPLACEACTIVATE:
  412.                 b = TRUE;
  413.                 break;
  414.         }
  415.         return b;
  416.     }
  417.  
  418.     BOOL SetControlFocus(BOOL bGrab);
  419.     HRESULT IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  420.         QACONTROL *pQACtrl);
  421.     HRESULT IPersistPropertyBag_Load(LPPROPERTYBAG pPropBag,
  422.         LPERRORLOG pErrorLog, ATL_PROPMAP_ENTRY* pMap);
  423.     HRESULT IPersistPropertyBag_Save(LPPROPERTYBAG pPropBag,
  424.         BOOL fClearDirty, BOOL fSaveAllProperties, ATL_PROPMAP_ENTRY* pMap);
  425.     HRESULT ISpecifyPropertyPages_GetPages(CAUUID* pPages,
  426.         ATL_PROPMAP_ENTRY* pMap);
  427.     HRESULT DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent);
  428.     HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL);
  429.     HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap);
  430.     HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */,
  431.         ATL_PROPMAP_ENTRY* pMap);
  432.  
  433.     HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite);
  434.     HRESULT IOleObject_GetClientSite(IOleClientSite **ppClientSite);
  435.     HRESULT IOleObject_Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
  436.     HRESULT IOleObject_Close(DWORD dwSaveOption);
  437.     HRESULT IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
  438.     HRESULT IOleInPlaceObject_InPlaceDeactivate(void);
  439.     HRESULT IOleInPlaceObject_UIDeactivate(void);
  440.     HRESULT IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip);
  441.     HRESULT IViewObject_Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  442.         DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  443.         LPCRECTL prcBounds, LPCRECTL prcWBounds);
  444.     HRESULT IDataObject_GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
  445.  
  446.     HRESULT FireViewChange();
  447.     LRESULT OnPaint(UINT /* nMsg */, WPARAM /* wParam */, LPARAM /* lParam */,
  448.         BOOL& /* lResult */);
  449.  
  450.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) = 0;
  451.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) = 0;
  452.     virtual HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
  453.     virtual HRESULT OnDraw(ATL_DRAWINFO& di)
  454.     {
  455.         return S_OK;
  456.     }
  457.  
  458.  
  459. // Attributes
  460. public:
  461.     CComPtr<IOleInPlaceSiteWindowless> m_spInPlaceSite;
  462.     CComPtr<IDataAdviseHolder> m_spDataAdviseHolder;
  463.     CComPtr<IOleAdviseHolder> m_spOleAdviseHolder;
  464.     CComPtr<IOleClientSite> m_spClientSite;
  465.     CComPtr<IAdviseSink> m_spAdviseSink;
  466.     CComDispatchDriver m_spAmbientDispatch;
  467.  
  468.     SIZE m_sizeNatural; //unscaled size in himetric
  469.     SIZE m_sizeExtent;  //current extents in himetric
  470.     RECT m_rcPos; // position in pixels
  471.     union
  472.     {
  473.         HWND& m_hWndCD;
  474.         HWND* m_phWndCD;
  475.     };
  476.     union
  477.     {
  478.         // m_nFreezeEvents is the only one actually used
  479.         int m_nFreezeEvents; // count of freezes versus thaws
  480.  
  481.         // These are here to make stock properties work
  482.         IPictureDisp* m_pMouseIcon;
  483.         IPictureDisp* m_pPicture;
  484.         IFontDisp* m_pFont;
  485.         OLE_COLOR m_clrBackColor;
  486.         OLE_COLOR m_clrBorderColor;
  487.         OLE_COLOR m_clrFillColor;
  488.         OLE_COLOR m_clrForeColor;
  489.         BSTR m_bstrText;
  490.         BSTR m_bstrCaption;
  491.         BOOL m_bValid;
  492.         BOOL m_bTabStop;
  493.         BOOL m_bBorderVisible;
  494.         BOOL m_bEnabled;
  495.         long m_nBackStyle;
  496.         long m_nBorderStyle;
  497.         long m_nBorderWidth;
  498.         long m_nDrawMode;
  499.         long m_nDrawStyle;
  500.         long m_nDrawWidth;
  501.         long m_nFillStyle;
  502.         long m_nAppearance;
  503.         long m_nMousePointer;
  504.         long m_nReadyState;
  505.     };
  506.  
  507.     unsigned m_bNegotiatedWnd:1;
  508.     unsigned m_bWndLess:1;
  509.     unsigned m_bInPlaceActive:1;
  510.     unsigned m_bUIActive:1;
  511.     unsigned m_bUsingWindowRgn:1;
  512.     unsigned m_bInPlaceSiteEx:1;
  513.     unsigned m_bWindowOnly:1;
  514.     unsigned m_bRequiresSave:1;
  515.     unsigned m_bWasOnceWindowless:1;
  516.     unsigned m_bAutoSize:1; //SetExtent fails if size doesn't match existing
  517.     unsigned m_bRecomposeOnResize:1; //implies OLEMISC_RECOMPOSEONRESIZE
  518.     unsigned m_bResizeNatural:1;  //resize natural extent on SetExtent
  519.     unsigned m_bDrawFromNatural:1; //instead of m_sizeExtent
  520.     unsigned m_bDrawGetDataInHimetric:1; //instead of pixels
  521. };
  522.  
  523. template <class T>
  524. class ATL_NO_VTABLE CComControl :  public CComControlBase, public CWindowImpl<T>
  525. {
  526. public:
  527.     CComControl() : CComControlBase(m_hWnd) {}
  528.     HRESULT FireOnRequestEdit(DISPID dispID)
  529.     {
  530.         T* pT = static_cast<T*>(this);
  531.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
  532.     }
  533.     HRESULT FireOnChanged(DISPID dispID)
  534.     {
  535.         T* pT = static_cast<T*>(this);
  536.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
  537.     }
  538.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
  539.     {
  540.         T* pT = static_cast<T*>(this);
  541.         return pT->_InternalQueryInterface(iid, ppv);
  542.     }
  543.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  544.     {
  545.         T* pT = static_cast<T*>(this);
  546.         return pT->Create(hWndParent, rcPos);
  547.     }
  548. };
  549.  
  550. // Forward declarations
  551. //
  552. template <class T> class IPersistImpl;
  553. template <class T> class IPersistStreamInitImpl;
  554. template <class T> class IPersistStorageImpl;
  555. template <class T> class IPersistPropertyBagImpl;
  556.  
  557. template <class T> class IOleControlImpl;
  558. template <class T> class IRunnableObjectImpl;
  559. template <class T> class IQuickActivateImpl;
  560. template <class T> class IOleObjectImpl;
  561. template <class T> class IPropertyPageImpl;
  562. template <class T> class IPropertyPage2Impl;
  563. template <class T> class IPerPropertyBrowsingImpl;
  564. template <class T> class IViewObjectExImpl;
  565. template <class T> class IOleWindowImpl;
  566. template <class T> class ISpecifyPropertyPagesImpl;
  567. template <class T> class IPointerInactiveImpl;
  568. template <class T, class CDV > class IPropertyNotifySinkCP;
  569. template <class T> class IBindStatusCallbackImpl;
  570. template <class T> class CBindStatusCallback;
  571.  
  572. //////////////////////////////////////////////////////////////////////////////
  573. // IPersistImpl
  574. template <class T>
  575. class ATL_NO_VTABLE IPersistImpl
  576. {
  577. public:
  578.     // IUnknown
  579.     //
  580.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  581.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistImpl)
  582.  
  583.     // IPersist
  584.     STDMETHOD(GetClassID)(CLSID *pClassID)
  585.     {
  586.         ATLTRACE(_T("IPersistImpl::GetClassID\n"));
  587.         T* pT = static_cast<T*>(this);
  588.         *pClassID = pT->GetObjectCLSID();
  589.         return S_OK;
  590.     }
  591. };
  592.  
  593. #define BEGIN_PROPERTY_MAP(theClass) \
  594.     typedef _ATL_PROP_NOTIFY_EVENT_CLASS __ATL_PROP_NOTIFY_EVENT_CLASS; \
  595.     static ATL_PROPMAP_ENTRY* GetPropertyMap()\
  596.     {\
  597.         static ATL_PROPMAP_ENTRY pPropMap[] = \
  598.         {
  599.  
  600. #define PROP_ENTRY(szDesc, dispid, clsid) \
  601.         {OLESTR(szDesc), dispid, &clsid, &IID_IDispatch},
  602.  
  603. #define PROP_ENTRY_EX(szDesc, dispid, clsid, iidDispatch) \
  604.         {OLESTR(szDesc), dispid, &clsid, &iidDispatch},
  605.  
  606. #define PROP_PAGE(clsid) \
  607.         {NULL, NULL, &clsid, &IID_NULL},
  608.  
  609. #define END_PROPERTY_MAP() \
  610.             {NULL, 0, NULL, &IID_NULL} \
  611.         }; \
  612.         return pPropMap; \
  613.     }
  614.  
  615.  
  616. //////////////////////////////////////////////////////////////////////////////
  617. // IPersistStreamInitImpl
  618. template <class T>
  619. class ATL_NO_VTABLE IPersistStreamInitImpl
  620. {
  621. public:
  622.     // IUnknown
  623.     //
  624.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  625.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStreamInitImpl)
  626.  
  627.     // IPersist
  628.     STDMETHOD(GetClassID)(CLSID *pClassID)
  629.     {
  630.         ATLTRACE(_T("IPersistStreamInitImpl::GetClassID\n"));
  631.         T* pT = static_cast<T*>(this);
  632.         *pClassID = pT->GetObjectCLSID();
  633.         return S_OK;
  634.     }
  635.  
  636.     // IPersistStream
  637.     STDMETHOD(IsDirty)()
  638.     {
  639.         ATLTRACE(_T("IPersistStreamInitImpl::IsDirty\n"));
  640.         T* pT = static_cast<T*>(this);
  641.         return (pT->m_bRequiresSave) ? S_OK : S_FALSE;
  642.     }
  643.     STDMETHOD(Load)(LPSTREAM pStm)
  644.     {
  645.         ATLTRACE(_T("IPersistStreamInitImpl::Load\n"));
  646.         T* pT = static_cast<T*>(this);
  647.         return pT->IPersistStreamInit_Load(pStm, T::GetPropertyMap());
  648.     }
  649.     STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty)
  650.     {
  651.         T* pT = static_cast<T*>(this);
  652.         ATLTRACE(_T("IPersistStreamInitImpl::Save\n"));
  653.         return pT->IPersistStreamInit_Save(pStm, fClearDirty, T::GetPropertyMap());
  654.     }
  655.     STDMETHOD(GetSizeMax)(ULARGE_INTEGER FAR* /* pcbSize */)
  656.     {
  657.         ATLTRACENOTIMPL(_T("IPersistStreamInitImpl::GetSizeMax"));
  658.     }
  659.  
  660.     // IPersistStreamInit
  661.     STDMETHOD(InitNew)()
  662.     {
  663.         T* pT = static_cast<T*>(this);
  664.         ATLTRACE(_T("IPersistStreamInitImpl::InitNew\n"));
  665.         pT->SendOnDataChange();
  666.         return S_OK;
  667.     }
  668.  
  669. };
  670.  
  671.  
  672. //////////////////////////////////////////////////////////////////////////////
  673. // IPersistStorageImpl
  674. template <class T>
  675. class ATL_NO_VTABLE IPersistStorageImpl
  676. {
  677. public:
  678.     // IUnknown
  679.     //
  680.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  681.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistStorageImpl)
  682.  
  683.     // IPersist
  684.     STDMETHOD(GetClassID)(CLSID *pClassID)
  685.     {
  686.         ATLTRACE(_T("IPersistStorageImpl::GetClassID\n"));
  687.         T* pT = static_cast<T*>(this);
  688.         *pClassID = pT->GetObjectCLSID();
  689.         return S_OK;
  690.     }
  691.  
  692.     // IPersistStorage
  693.     STDMETHOD(IsDirty)(void)
  694.     {
  695.         ATLTRACE(_T("IPersistStorageImpl::IsDirty\n"));
  696.         T* pT = static_cast<T*>(this);
  697.         CComPtr<IPersistStreamInit> p;
  698.         p.p = IPSI_GetIPersistStreamInit();
  699.         return (p != NULL) ? p->IsDirty() : E_FAIL;
  700.     }
  701.     STDMETHOD(InitNew)(IStorage*)
  702.     {
  703.         ATLTRACE(_T("IPersistStorageImpl::InitNew\n"));
  704.         T* pT = static_cast<T*>(this);
  705.         CComPtr<IPersistStreamInit> p;
  706.         p.p = IPSI_GetIPersistStreamInit();
  707.         return (p != NULL) ? p->InitNew() : E_FAIL;
  708.     }
  709.     STDMETHOD(Load)(IStorage* pStorage)
  710.     {
  711.         ATLTRACE(_T("IPersistStorageImpl::Load\n"));
  712.         T* pT = static_cast<T*>(this);
  713.         CComPtr<IPersistStreamInit> p;
  714.         p.p = IPSI_GetIPersistStreamInit();
  715.         HRESULT hr = E_FAIL;
  716.         if (p != NULL)
  717.         {
  718.             CComPtr<IStream> spStream;
  719.             hr = pStorage->OpenStream(OLESTR("Contents"), NULL,
  720.                 STGM_DIRECT | STGM_SHARE_EXCLUSIVE, 0, &spStream);
  721.             if (SUCCEEDED(hr))
  722.                 hr = p->Load(spStream);
  723.         }
  724.         return hr;
  725.     }
  726.     STDMETHOD(Save)(IStorage* pStorage, BOOL fSameAsLoad)
  727.     {
  728.         ATLTRACE(_T("IPersistStorageImpl::Save\n"));
  729.         T* pT = static_cast<T*>(this);
  730.         CComPtr<IPersistStreamInit> p;
  731.         p.p = IPSI_GetIPersistStreamInit();
  732.         HRESULT hr = E_FAIL;
  733.         if (p != NULL)
  734.         {
  735.             CComPtr<IStream> spStream;
  736.             static LPCOLESTR vszContents = OLESTR("Contents");
  737.             hr = pStorage->CreateStream(vszContents,
  738.                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  739.                 0, 0, &spStream);
  740.             if (SUCCEEDED(hr))
  741.                 hr = p->Save(spStream, fSameAsLoad);
  742.         }
  743.         return hr;
  744.     }
  745.     STDMETHOD(SaveCompleted)(IStorage* /* pStorage */)
  746.     {
  747.         ATLTRACE(_T("IPersistStorageImpl::SaveCompleted\n"));
  748.         return S_OK;
  749.     }
  750.     STDMETHOD(HandsOffStorage)(void)
  751.     {
  752.         ATLTRACE(_T("IPersistStorageImpl::HandsOffStorage\n"));
  753.         return S_OK;
  754.     }
  755. private:
  756.     IPersistStreamInit* IPSI_GetIPersistStreamInit();
  757. };
  758.  
  759. template <class T>
  760. IPersistStreamInit* IPersistStorageImpl<T>::IPSI_GetIPersistStreamInit()
  761. {
  762.     T* pT = static_cast<T*>(this);
  763.     IPersistStreamInit* p;
  764.     if (FAILED(pT->GetUnknown()->QueryInterface(IID_IPersistStreamInit, (void**)&p)))
  765.         pT->_InternalQueryInterface(IID_IPersistStreamInit, (void**)&p);
  766.     return p;
  767. }
  768.  
  769. //////////////////////////////////////////////////////////////////////////////
  770. // IPersistPropertyBagImpl
  771. template <class T>
  772. class ATL_NO_VTABLE IPersistPropertyBagImpl
  773. {
  774. public:
  775.  
  776.     // IUnknown
  777.     //
  778.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  779.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistPropertyBagImpl)
  780.  
  781.     // IPersist
  782.     STDMETHOD(GetClassID)(CLSID *pClassID)
  783.     {
  784.         ATLTRACE(_T("IPersistPropertyBagImpl::GetClassID\n"));
  785.         T* pT = static_cast<T*>(this);
  786.         *pClassID = pT->GetObjectCLSID();
  787.         return S_OK;
  788.     }
  789.  
  790.     // IPersistPropertyBag
  791.     //
  792.     STDMETHOD(InitNew)()
  793.     {
  794.         ATLTRACE(_T("IPersistPropertyBagImpl::InitNew\n"));
  795.         return S_OK;
  796.     }
  797.     STDMETHOD(Load)(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
  798.     {
  799.         ATLTRACE(_T("IPersistPropertyBagImpl::Load\n"));
  800.         T* pT = static_cast<T*>(this);
  801.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  802.         _ASSERTE(pMap != NULL);
  803.         return pT->IPersistPropertyBag_Load(pPropBag, pErrorLog, pMap);
  804.     }
  805.     STDMETHOD(Save)(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
  806.     {
  807.         ATLTRACE(_T("IPersistPropertyBagImpl::Save\n"));
  808.         T* pT = static_cast<T*>(this);
  809.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  810.         _ASSERTE(pMap != NULL);
  811.         return pT->IPersistPropertyBag_Save(pPropBag, fClearDirty, fSaveAllProperties, pMap);
  812.     }
  813. };
  814.  
  815.  
  816. //////////////////////////////////////////////////////////////////////////////
  817. // IOleControlImpl
  818. template <class T>
  819. class ATL_NO_VTABLE IOleControlImpl
  820. {
  821. public:
  822.     // IUnknown
  823.     //
  824.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  825.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl)
  826.  
  827.     // IOleControl methods
  828.     //
  829.     STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */)
  830.     {
  831.         ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo"));
  832.     }
  833.     STDMETHOD(OnMnemonic)(LPMSG /* pMsg */)
  834.     {
  835.         ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic"));
  836.     }
  837.     STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
  838.     {
  839.         dispid;
  840.         ATLTRACE(_T("IOleControlImpl::OnAmbientPropertyChange\n"));
  841.         ATLTRACE(_T(" -- DISPID = %d (%d)\n"), dispid);
  842.         return S_OK;
  843.     }
  844.     STDMETHOD(FreezeEvents)(BOOL bFreeze)
  845.     {
  846.         T* pT = static_cast<T*>(this);
  847.         ATLTRACE(_T("IOleControlImpl::FreezeEvents\n"));
  848.         if (bFreeze)
  849.             pT->m_nFreezeEvents++;
  850.         else
  851.             pT->m_nFreezeEvents--;
  852.         return S_OK;
  853.     }
  854. };
  855.  
  856.  
  857. //////////////////////////////////////////////////////////////////////////////
  858. // IQuickActivateImpl
  859. template <class T>
  860. class ATL_NO_VTABLE IQuickActivateImpl
  861. {
  862. public:
  863.     // IUnknown
  864.     //
  865.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  866.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IQuickActivateImpl)
  867.  
  868.     // IQuickActivate
  869.     //
  870.     STDMETHOD(QuickActivate)(QACONTAINER *pQACont, QACONTROL *pQACtrl)
  871.     {
  872.         T* pT = static_cast<T*>(this);
  873.         ATLTRACE(_T("IQuickActivateImpl::QuickActivate\n"));
  874.         return pT->IQuickActivate_QuickActivate(pQACont, pQACtrl);
  875.     }
  876.     STDMETHOD(SetContentExtent)(LPSIZEL pSize)
  877.     {
  878.         T* pT = static_cast<T*>(this);
  879.         ATLTRACE(_T("IQuickActivateImpl::SetContentExtent\n"));
  880.         return pT->IOleObjectImpl<T>::SetExtent(DVASPECT_CONTENT, pSize);
  881.     }
  882.     STDMETHOD(GetContentExtent)(LPSIZEL pSize)
  883.     {
  884.         T* pT = static_cast<T*>(this);
  885.         ATLTRACE(_T("IQuickActivateImpl::GetContentExtent\n"));
  886.         return pT->IOleObjectImpl<T>::GetExtent(DVASPECT_CONTENT, pSize);
  887.     }
  888. };
  889.  
  890.  
  891. //////////////////////////////////////////////////////////////////////////////
  892. // IOleObjectImpl
  893. template <class T>
  894. class ATL_NO_VTABLE IOleObjectImpl
  895. {
  896. public:
  897.     // IUnknown
  898.     //
  899.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  900.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleObjectImpl)
  901.  
  902.     // IOleObject
  903.     //
  904.     STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
  905.     {
  906.         T* pT = static_cast<T*>(this);
  907.         ATLTRACE(_T("IOleObjectImpl::SetClientSite\n"));
  908.         return pT->IOleObject_SetClientSite(pClientSite);
  909.     }
  910.     STDMETHOD(GetClientSite)(IOleClientSite **ppClientSite)
  911.     {
  912.         T* pT = static_cast<T*>(this);
  913.         ATLTRACE(_T("IOleObjectImpl::GetClientSite\n"));
  914.         return pT->IOleObject_GetClientSite(ppClientSite);
  915.     }
  916.     STDMETHOD(SetHostNames)(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */)
  917.     {
  918.         ATLTRACE(_T("IOleObjectImpl::SetHostNames\n"));
  919.         return S_OK;
  920.     }
  921.     STDMETHOD(Close)(DWORD dwSaveOption)
  922.     {
  923.         T* pT = static_cast<T*>(this);
  924.         ATLTRACE(_T("IOleObjectImpl::Close\n"));
  925.         return pT->IOleObject_Close(dwSaveOption);
  926.     }
  927.     STDMETHOD(SetMoniker)(DWORD /* dwWhichMoniker */, IMoniker* /* pmk */)
  928.     {
  929.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker"));
  930.     }
  931.     STDMETHOD(GetMoniker)(DWORD /* dwAssign */, DWORD /* dwWhichMoniker */, IMoniker** /* ppmk */)
  932.     {
  933.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetMoniker"));
  934.     }
  935.     STDMETHOD(InitFromData)(IDataObject* /* pDataObject */, BOOL /* fCreation */, DWORD /* dwReserved */)
  936.     {
  937.         ATLTRACENOTIMPL(_T("IOleObjectImpl::InitFromData"));
  938.     }
  939.     STDMETHOD(GetClipboardData)(DWORD /* dwReserved */, IDataObject** /* ppDataObject */)
  940.     {
  941.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetClipboardData"));
  942.     }
  943.  
  944.     // Helpers for DoVerb - Over-rideable in user class
  945.     HRESULT DoVerbPrimary(LPCRECT prcPosRect, HWND hwndParent)
  946.     {
  947.         T* pT = static_cast<T*>(this);
  948.         BOOL bDesignMode = FALSE;
  949.         CComVariant var;
  950.         // if container doesn't support this property
  951.         // don't allow design mode
  952.         HRESULT hRes = pT->GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  953.         if (SUCCEEDED(hRes) && var.vt == VT_BOOL && !var.boolVal)
  954.             bDesignMode = TRUE;
  955.         if (bDesignMode)
  956.             return pT->DoVerbProperties(prcPosRect, hwndParent);
  957.         else
  958.             return pT->DoVerbInPlaceActivate(prcPosRect, hwndParent);
  959.     }
  960.     HRESULT DoVerbShow(LPCRECT prcPosRect, HWND /* hwndParent */)
  961.     {
  962.         T* pT = static_cast<T*>(this);
  963.         return pT->InPlaceActivate(OLEIVERB_SHOW, prcPosRect);
  964.     }
  965.     HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  966.     {
  967.         T* pT = static_cast<T*>(this);
  968.         return pT->InPlaceActivate(OLEIVERB_INPLACEACTIVATE, prcPosRect);
  969.     }
  970.     HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  971.     {
  972.         T* pT = static_cast<T*>(this);
  973.         return pT->InPlaceActivate(OLEIVERB_UIACTIVATE, prcPosRect);
  974.     }
  975.     HRESULT DoVerbHide(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  976.     {
  977.         T* pT = static_cast<T*>(this);
  978.         pT->UIDeactivate();
  979.         if (pT->m_hWnd)
  980.             pT->ShowWindow(SW_HIDE);
  981.         return S_OK;
  982.     }
  983.     HRESULT DoVerbOpen(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  984.     {
  985.         return S_OK;
  986.     }
  987.     HRESULT DoVerbDiscardUndo(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  988.     {
  989.         return S_OK;
  990.     }
  991.     STDMETHOD(DoVerb)(LONG iVerb, LPMSG /* lpmsg */, IOleClientSite* /* pActiveSite */, LONG /* lindex */,
  992.                                      HWND hwndParent, LPCRECT lprcPosRect)
  993.     {
  994.         T* pT = static_cast<T*>(this);
  995.         ATLTRACE(_T("IOleObjectImpl::DoVerb\n"));
  996.         _ASSERTE(pT->m_spClientSite);
  997.  
  998.         HRESULT hr = E_NOTIMPL;
  999.         switch (iVerb)
  1000.         {
  1001.         case OLEIVERB_PRIMARY:
  1002.             hr = pT->DoVerbPrimary(lprcPosRect, hwndParent);
  1003.             break;
  1004.         case OLEIVERB_SHOW:
  1005.             hr = pT->DoVerbShow(lprcPosRect, hwndParent);
  1006.             break;
  1007.         case OLEIVERB_INPLACEACTIVATE:
  1008.             hr = pT->DoVerbInPlaceActivate(lprcPosRect, hwndParent);
  1009.             break;
  1010.         case OLEIVERB_UIACTIVATE:
  1011.             hr = pT->DoVerbUIActivate(lprcPosRect, hwndParent);
  1012.             break;
  1013.         case OLEIVERB_HIDE:
  1014.             hr = pT->DoVerbHide(lprcPosRect, hwndParent);
  1015.             break;
  1016.         case OLEIVERB_OPEN:
  1017.             hr = pT->DoVerbOpen(lprcPosRect, hwndParent);
  1018.             break;
  1019.         case OLEIVERB_DISCARDUNDOSTATE:
  1020.             hr = pT->DoVerbDiscardUndo(lprcPosRect, hwndParent);
  1021.             break;
  1022.         case OLEIVERB_PROPERTIES:
  1023.             hr = pT->DoVerbProperties(lprcPosRect, hwndParent);
  1024.         }
  1025.         return hr;
  1026.     }
  1027.     STDMETHOD(EnumVerbs)(IEnumOLEVERB **ppEnumOleVerb)
  1028.     {
  1029.         ATLTRACE(_T("IOleObjectImpl::EnumVerbs\n"));
  1030.         _ASSERTE(ppEnumOleVerb);
  1031.         if (!ppEnumOleVerb)
  1032.             return E_POINTER;
  1033.         return OleRegEnumVerbs(T::GetObjectCLSID(), ppEnumOleVerb);
  1034.     }
  1035.     STDMETHOD(Update)(void)
  1036.     {
  1037.         ATLTRACE(_T("IOleObjectImpl::Update\n"));
  1038.         return S_OK;
  1039.     }
  1040.     STDMETHOD(IsUpToDate)(void)
  1041.     {
  1042.         ATLTRACE(_T("IOleObjectImpl::IsUpToDate\n"));
  1043.         return S_OK;
  1044.     }
  1045.     STDMETHOD(GetUserClassID)(CLSID *pClsid)
  1046.     {
  1047.         ATLTRACE(_T("IOleObjectImpl::GetUserClassID\n"));
  1048.         _ASSERTE(pClsid);
  1049.         if (!pClsid)
  1050.             return E_POINTER;
  1051.         *pClsid = T::GetObjectCLSID();
  1052.         return S_OK;
  1053.     }
  1054.     STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType)
  1055.     {
  1056.         ATLTRACE(_T("IOleObjectImpl::GetUserType\n"));
  1057.         return OleRegGetUserType(T::GetObjectCLSID(), dwFormOfType, pszUserType);
  1058.     }
  1059.     STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1060.     {
  1061.         T* pT = static_cast<T*>(this);
  1062.         ATLTRACE(_T("IOleObjectImpl::SetExtent\n"));
  1063.         return pT->IOleObject_SetExtent(dwDrawAspect, psizel);
  1064.     }
  1065.     STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1066.     {
  1067.         T* pT = static_cast<T*>(this);
  1068.         ATLTRACE(_T("IOleObjectImpl::GetExtent\n"));
  1069.         if (dwDrawAspect != DVASPECT_CONTENT)
  1070.             return E_FAIL;
  1071.         if (psizel == NULL)
  1072.             return E_POINTER;
  1073.         *psizel = pT->m_sizeExtent;
  1074.         return S_OK;
  1075.     }
  1076.     STDMETHOD(Advise)(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  1077.     {
  1078.         T* pT = static_cast<T*>(this);
  1079.         ATLTRACE(_T("IOleObjectImpl::Advise\n"));
  1080.         return pT->IOleObject_Advise(pAdvSink, pdwConnection);
  1081.     }
  1082.     STDMETHOD(Unadvise)(DWORD dwConnection)
  1083.     {
  1084.         T* pT = static_cast<T*>(this);
  1085.         ATLTRACE(_T("IOleObjectImpl::Unadvise\n"));
  1086.         HRESULT hRes = E_FAIL;
  1087.         if (pT->m_spOleAdviseHolder != NULL)
  1088.             hRes = pT->m_spOleAdviseHolder->Unadvise(dwConnection);
  1089.         return hRes;
  1090.     }
  1091.     STDMETHOD(EnumAdvise)(IEnumSTATDATA **ppenumAdvise)
  1092.     {
  1093.         T* pT = static_cast<T*>(this);
  1094.         ATLTRACE(_T("IOleObjectImpl::EnumAdvise\n"));
  1095.         HRESULT hRes = E_FAIL;
  1096.         if (pT->m_spOleAdviseHolder != NULL)
  1097.             hRes = pT->m_spOleAdviseHolder->EnumAdvise(ppenumAdvise);
  1098.         return hRes;
  1099.     }
  1100.     STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus)
  1101.     {
  1102.         ATLTRACE(_T("IOleObjectImpl::GetMiscStatus\n"));
  1103.         return OleRegGetMiscStatus(T::GetObjectCLSID(), dwAspect, pdwStatus);
  1104.     }
  1105.     STDMETHOD(SetColorScheme)(LOGPALETTE* /* pLogpal */)
  1106.     {
  1107.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetColorScheme"));
  1108.     }
  1109. };
  1110.  
  1111. //local struct used for implementation
  1112. #pragma pack(push, 1)
  1113. struct _ATL_DLGTEMPLATEEX
  1114. {
  1115.     WORD dlgVer;
  1116.     WORD signature;
  1117.     DWORD helpID;
  1118.     DWORD exStyle;
  1119.     DWORD style;
  1120.     WORD cDlgItems;
  1121.     short x;
  1122.     short y;
  1123.     short cx;
  1124.     short cy;
  1125. };
  1126. #pragma pack(pop)
  1127.  
  1128. //////////////////////////////////////////////////////////////////////////////
  1129. // IPropertyPageImpl
  1130. template <class T>
  1131. class ATL_NO_VTABLE IPropertyPageImpl
  1132. {
  1133.  
  1134. public:
  1135.     // IUnknown
  1136.     //
  1137.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1138.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleControlImpl)
  1139.  
  1140.     void SetDirty(BOOL bDirty)
  1141.     {
  1142.         T* pT = static_cast<T*>(this);
  1143.         if (!pT->m_bDirty && bDirty)
  1144.             pT->m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE);
  1145.         pT->m_bDirty = bDirty;
  1146.     }
  1147.  
  1148.     IPropertyPageImpl()
  1149.     {
  1150.         T* pT = static_cast<T*>(this);
  1151.         pT->m_pPageSite = NULL;
  1152.         pT->m_size.cx = 0;
  1153.         pT->m_size.cy = 0;
  1154.         pT->m_dwTitleID = 0;
  1155.         pT->m_dwHelpFileID = 0;
  1156.         pT->m_dwDocStringID = 0;
  1157.         pT->m_dwHelpContext = 0;
  1158.         pT->m_ppUnk = NULL;
  1159.         pT->m_nObjects = 0;
  1160.         pT->m_bDirty = FALSE;
  1161.         pT->m_hWnd = NULL;
  1162.     }
  1163.  
  1164.     ~IPropertyPageImpl()
  1165.     {
  1166.         T* pT = static_cast<T*>(this);
  1167.         if (pT->m_pPageSite != NULL)
  1168.             pT->m_pPageSite->Release();
  1169.  
  1170.         for (UINT i = 0; i < m_nObjects; i++)
  1171.             pT->m_ppUnk[i]->Release();
  1172.  
  1173.         delete[] pT->m_ppUnk;
  1174.     }
  1175.  
  1176.     // IPropertyPage
  1177.     //
  1178.     STDMETHOD(SetPageSite)(IPropertyPageSite *pPageSite)
  1179.     {
  1180.         T* pT = static_cast<T*>(this);
  1181.         ATLTRACE(_T("IPropertyPageImpl::SetPageSite\n"));
  1182.  
  1183.         if (!pPageSite && pT->m_pPageSite)
  1184.         {
  1185.             pT->m_pPageSite->Release();
  1186.             return S_OK;
  1187.         }
  1188.  
  1189.         if (!pPageSite && !pT->m_pPageSite)
  1190.             return S_OK;
  1191.  
  1192.         if (pPageSite && pT->m_pPageSite)
  1193.         {
  1194.             ATLTRACE(_T("Error : setting page site again with non NULL value\n"));
  1195.             return E_UNEXPECTED;
  1196.         }
  1197.  
  1198.         pT->m_pPageSite = pPageSite;
  1199.         pT->m_pPageSite->AddRef();
  1200.         return S_OK;
  1201.     }
  1202.     STDMETHOD(Activate)(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */)
  1203.     {
  1204.         T* pT = static_cast<T*>(this);
  1205.         ATLTRACE(_T("IPropertyPageImpl::Activate\n"));
  1206.  
  1207.         if (pRect == NULL)
  1208.         {
  1209.             ATLTRACE(_T("Error : Passed a NULL rect\n"));
  1210.             return E_POINTER;
  1211.         }
  1212.  
  1213.         pT->m_hWnd = pT->Create(hWndParent);
  1214.         Move(pRect);
  1215.  
  1216.         m_size.cx = pRect->right - pRect->left;
  1217.         m_size.cy = pRect->bottom - pRect->top;
  1218.  
  1219.         return S_OK;
  1220.  
  1221.     }
  1222.     STDMETHOD(Deactivate)( void)
  1223.     {
  1224.         T* pT = static_cast<T*>(this);
  1225.         ATLTRACE(_T("IPropertyPageImpl::Deactivate\n"));
  1226.  
  1227.         if (pT->m_hWnd)
  1228.         {
  1229.             ATLTRACE(_T("Destroying Dialog\n"));
  1230.             if (::IsWindow(pT->m_hWnd))
  1231.                 pT->DestroyWindow();
  1232.             pT->m_hWnd = NULL;
  1233.         }
  1234.  
  1235.         return S_OK;
  1236.  
  1237.     }
  1238.     STDMETHOD(GetPageInfo)(PROPPAGEINFO *pPageInfo)
  1239.     {
  1240.         T* pT = static_cast<T*>(this);
  1241.         ATLTRACE(_T("IPropertyPageImpl::GetPageInfo\n"));
  1242.  
  1243.         if (pPageInfo == NULL)
  1244.         {
  1245.             ATLTRACE(_T("Error : PROPPAGEINFO passed == NULL\n"));
  1246.             return E_POINTER;
  1247.         }
  1248.  
  1249.         HRSRC hRsrc = FindResource(_Module.GetResourceInstance(),
  1250.                                    MAKEINTRESOURCE(T::IDD), RT_DIALOG);
  1251.         if (hRsrc == NULL)
  1252.         {
  1253.             ATLTRACE(_T("Could not find resource template\n"));
  1254.             return E_UNEXPECTED;
  1255.         }
  1256.  
  1257.         HGLOBAL hGlob = LoadResource(_Module.GetResourceInstance(), hRsrc);
  1258.         DLGTEMPLATE* pTemp = (DLGTEMPLATE*)LockResource(hGlob);
  1259.         if (pTemp == NULL)
  1260.         {
  1261.             ATLTRACE(_T("Could not load resource template\n"));
  1262.             return E_UNEXPECTED;
  1263.         }
  1264.         pT->GetDialogSize(pTemp, &m_size);
  1265.  
  1266.         pPageInfo->cb = sizeof(PROPPAGEINFO);
  1267.         pPageInfo->pszTitle = LoadStringHelper(pT->m_dwTitleID);
  1268.         pPageInfo->size = m_size;
  1269.         pPageInfo->pszHelpFile = LoadStringHelper(pT->m_dwHelpFileID);
  1270.         pPageInfo->pszDocString = LoadStringHelper(pT->m_dwDocStringID);
  1271.         pPageInfo->dwHelpContext = pT->m_dwHelpContext;
  1272.  
  1273.         return S_OK;
  1274.     }
  1275.  
  1276.     STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk)
  1277.     {
  1278.         T* pT = static_cast<T*>(this);
  1279.         ATLTRACE(_T("IPropertyPageImpl::SetObjects\n"));
  1280.  
  1281.         if (ppUnk == NULL)
  1282.             return E_POINTER;
  1283.  
  1284.         if (pT->m_ppUnk != NULL && pT->m_nObjects > 0)
  1285.         {
  1286.             for (UINT iObj = 0; iObj < pT->m_nObjects; iObj++)
  1287.                 pT->m_ppUnk[iObj]->Release();
  1288.  
  1289.             delete [] pT->m_ppUnk;
  1290.         }
  1291.  
  1292.         pT->m_ppUnk = NULL;
  1293.         ATLTRY(pT->m_ppUnk = new IUnknown*[nObjects]);
  1294.  
  1295.         if (pT->m_ppUnk == NULL)
  1296.             return E_OUTOFMEMORY;
  1297.  
  1298.         for (UINT i = 0; i < nObjects; i++)
  1299.         {
  1300.             ppUnk[i]->AddRef();
  1301.             pT->m_ppUnk[i] = ppUnk[i];
  1302.         }
  1303.  
  1304.         pT->m_nObjects = nObjects;
  1305.  
  1306.         return S_OK;
  1307.     }
  1308.     STDMETHOD(Show)(UINT nCmdShow)
  1309.     {
  1310.         T* pT = static_cast<T*>(this);
  1311.         ATLTRACE(_T("IPropertyPageImpl::Show\n"));
  1312.  
  1313.         if (pT->m_hWnd == NULL)
  1314.             return E_UNEXPECTED;
  1315.  
  1316.         ShowWindow(pT->m_hWnd, nCmdShow);
  1317.         return S_OK;
  1318.     }
  1319.     STDMETHOD(Move)(LPCRECT pRect)
  1320.     {
  1321.         T* pT = static_cast<T*>(this);
  1322.         ATLTRACE(_T("IPropertyPageImpl::Move\n"));
  1323.  
  1324.         if (pT->m_hWnd == NULL)
  1325.             return E_UNEXPECTED;
  1326.  
  1327.         if (pRect == NULL)
  1328.             return E_POINTER;
  1329.  
  1330.         MoveWindow(pT->m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left,
  1331.                  pRect->bottom - pRect->top, TRUE);
  1332.  
  1333.         return S_OK;
  1334.  
  1335.     }
  1336.     STDMETHOD(IsPageDirty)(void)
  1337.     {
  1338.         T* pT = static_cast<T*>(this);
  1339.         ATLTRACE(_T("IPropertyPageImpl::IsPageDirty\n"));
  1340.         return pT->m_bDirty ? S_OK : S_FALSE;
  1341.     }
  1342.     STDMETHOD(Apply)(void)
  1343.     {
  1344.         T* pT = static_cast<T*>(this);
  1345.         ATLTRACE(_T("IPropertyPageImpl::Apply\n"));
  1346.         return S_OK;
  1347.     }
  1348.     STDMETHOD(Help)(LPCOLESTR pszHelpDir)
  1349.     {
  1350.         T* pT = static_cast<T*>(this);
  1351.         USES_CONVERSION;
  1352.  
  1353.         ATLTRACE(_T("IPropertyPageImpl::Help\n"));
  1354.         WinHelp(pT->m_hWnd, OLE2CT(pszHelpDir), HELP_CONTEXTPOPUP, NULL);
  1355.         return S_OK;
  1356.     }
  1357.     STDMETHOD(TranslateAccelerator)(MSG *pMsg)
  1358.     {
  1359.         T* pT = static_cast<T*>(this);
  1360.         ATLTRACE(_T("IPropertyPageImpl::TranslateAccelerator\n"));
  1361.         if (pMsg == NULL)
  1362.             return E_POINTER;
  1363.         LRESULT lRes;
  1364.         return pT->ProcessWindowMessage(pT->m_hWnd, pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ? S_OK : S_FALSE;
  1365.     }
  1366.  
  1367.     IPropertyPageSite* m_pPageSite;
  1368.     IUnknown** m_ppUnk;
  1369.     ULONG m_nObjects;
  1370.     SIZE m_size;
  1371.     UINT m_dwTitleID;
  1372.     UINT m_dwHelpFileID;
  1373.     UINT m_dwDocStringID;
  1374.     DWORD m_dwHelpContext;
  1375.     BOOL m_bDirty;
  1376.  
  1377. //methods
  1378. public:
  1379.  
  1380.     BEGIN_MSG_MAP(IPropertyPageImpl<T>)
  1381.         MESSAGE_HANDLER(WM_STYLECHANGING, OnStyleChange)
  1382.     END_MSG_MAP()
  1383.  
  1384.     LRESULT OnStyleChange(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
  1385.     {
  1386.         if (wParam == GWL_EXSTYLE)
  1387.         {
  1388.             LPSTYLESTRUCT lpss = (LPSTYLESTRUCT) lParam;
  1389.             lpss->styleNew |= WS_EX_CONTROLPARENT;
  1390.             return 0;
  1391.         }
  1392.         return 1;
  1393.     }
  1394.  
  1395.     LPOLESTR LoadStringHelper(UINT idRes)
  1396.     {
  1397.         USES_CONVERSION;
  1398.  
  1399.         TCHAR szTemp[_MAX_PATH];
  1400.         LPOLESTR sz = (LPOLESTR)CoTaskMemAlloc(_MAX_PATH*sizeof(OLECHAR));
  1401.         if (sz == NULL)
  1402.             return NULL;
  1403.         sz[0] = NULL;
  1404.  
  1405.         if (LoadString(_Module.GetResourceInstance(), idRes, szTemp, _MAX_PATH))
  1406.             ocscpy(sz, T2OLE(szTemp));
  1407.         else
  1408.         {
  1409.             ATLTRACE(_T("Error : Failed to load string from res\n"));
  1410.         }
  1411.  
  1412.         return sz;
  1413.     }
  1414.  
  1415.     void GetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  1416.     {
  1417.         // If the dialog has a font we use it otherwise we default
  1418.         // to the system font.
  1419.         if (HasFont(pTemplate))
  1420.         {
  1421.             TCHAR szFace[LF_FACESIZE];
  1422.             WORD  wFontSize = 0;
  1423.             GetFont(pTemplate, szFace, &wFontSize);
  1424.             GetSizeInDialogUnits(pTemplate, pSize);
  1425.             ConvertDialogUnitsToPixels(szFace, wFontSize, pSize);
  1426.         }
  1427.         else
  1428.         {
  1429.             GetSizeInDialogUnits(pTemplate, pSize);
  1430.             LONG nDlgBaseUnits = GetDialogBaseUnits();
  1431.             pSize->cx = MulDiv(pSize->cx, LOWORD(nDlgBaseUnits), 4);
  1432.             pSize->cy = MulDiv(pSize->cy, HIWORD(nDlgBaseUnits), 8);
  1433.         }
  1434.     }
  1435.  
  1436.     static void ConvertDialogUnitsToPixels(LPCTSTR pszFontFace, WORD wFontSize, SIZE* pSizePixel)
  1437.     {
  1438.         // Attempt to create the font to be used in the dialog box
  1439.         UINT cxSysChar, cySysChar;
  1440.         LOGFONT lf;
  1441.         HDC hDC = ::GetDC(NULL);
  1442.         int cxDlg = pSizePixel->cx;
  1443.         int cyDlg = pSizePixel->cy;
  1444.  
  1445.         ZeroMemory(&lf, sizeof(LOGFONT));
  1446.         lf.lfHeight = -MulDiv(wFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  1447.         lf.lfWeight = FW_NORMAL;
  1448.         lf.lfCharSet = DEFAULT_CHARSET;
  1449.         lstrcpy(lf.lfFaceName, pszFontFace);
  1450.  
  1451.         HFONT hNewFont = CreateFontIndirect(&lf);
  1452.         if (hNewFont != NULL)
  1453.         {
  1454.             TEXTMETRIC  tm;
  1455.             SIZE        size;
  1456.             HFONT       hFontOld = (HFONT)SelectObject(hDC, hNewFont);
  1457.             GetTextMetrics(hDC, &tm);
  1458.             cySysChar = tm.tmHeight + tm.tmExternalLeading;
  1459.             ::GetTextExtentPoint(hDC,
  1460.                 _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52,
  1461.                 &size);
  1462.             cxSysChar = (size.cx + 26) / 52;
  1463.             SelectObject(hDC, hFontOld);
  1464.             DeleteObject(hNewFont);
  1465.         }
  1466.         else
  1467.         {
  1468.             // Could not create the font so just use the system's values
  1469.             cxSysChar = LOWORD(GetDialogBaseUnits());
  1470.             cySysChar = HIWORD(GetDialogBaseUnits());
  1471.         }
  1472.         ::ReleaseDC(NULL, hDC);
  1473.  
  1474.         // Translate dialog units to pixels
  1475.         pSizePixel->cx = MulDiv(cxDlg, cxSysChar, 4);
  1476.         pSizePixel->cy = MulDiv(cyDlg, cySysChar, 8);
  1477.     }
  1478.  
  1479.     static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  1480.     {
  1481.         return ((_ATL_DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  1482.     }
  1483.  
  1484.     static BOOL HasFont(const DLGTEMPLATE* pTemplate)
  1485.     {
  1486.         return (DS_SETFONT &
  1487.             (IsDialogEx(pTemplate) ?
  1488.                 ((_ATL_DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
  1489.     }
  1490.  
  1491.     static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate)
  1492.     {
  1493.         BOOL bDialogEx = IsDialogEx(pTemplate);
  1494.         WORD* pw;
  1495.  
  1496.         if (bDialogEx)
  1497.             pw = (WORD*)((_ATL_DLGTEMPLATEEX*)pTemplate + 1);
  1498.         else
  1499.             pw = (WORD*)(pTemplate + 1);
  1500.  
  1501.         if (*pw == (WORD)-1)        // Skip menu name string or ordinal
  1502.             pw += 2; // WORDs
  1503.         else
  1504.             while(*pw++);
  1505.  
  1506.         if (*pw == (WORD)-1)        // Skip class name string or ordinal
  1507.             pw += 2; // WORDs
  1508.         else
  1509.             while(*pw++);
  1510.  
  1511.         while (*pw++);          // Skip caption string
  1512.  
  1513.         return (BYTE*)pw;
  1514.     }
  1515.  
  1516.     static BOOL GetFont(const DLGTEMPLATE* pTemplate, TCHAR* pszFace, WORD* pFontSize)
  1517.     {
  1518.         USES_CONVERSION;
  1519.         if (!HasFont(pTemplate))
  1520.             return FALSE;
  1521.  
  1522.         BYTE* pb = GetFontSizeField(pTemplate);
  1523.         *pFontSize = *(WORD*)pb;
  1524.         // Skip over font attributes to get to the font name
  1525.         pb += sizeof(WORD) * (IsDialogEx(pTemplate) ? 3 : 1);
  1526.  
  1527.         _tcscpy(pszFace, W2T((WCHAR*)pb));
  1528.         return TRUE;
  1529.     }
  1530.  
  1531.     static void GetSizeInDialogUnits(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  1532.     {
  1533.         if (IsDialogEx(pTemplate))
  1534.         {
  1535.             pSize->cx = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cx;
  1536.             pSize->cy = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cy;
  1537.         }
  1538.         else
  1539.         {
  1540.             pSize->cx = pTemplate->cx;
  1541.             pSize->cy = pTemplate->cy;
  1542.         }
  1543.     }
  1544. };
  1545.  
  1546.  
  1547. //////////////////////////////////////////////////////////////////////////////
  1548. // IPropertyPage2Impl
  1549. template <class T>
  1550. class ATL_NO_VTABLE IPropertyPage2Impl : public IPropertyPageImpl<T>
  1551. {
  1552. public:
  1553.  
  1554.     STDMETHOD(EditProperty)(DISPID dispID)
  1555.     {
  1556.         ATLTRACENOTIMPL(_T("IPropertyPage2Impl::EditProperty\n"));
  1557.     }
  1558. };
  1559.  
  1560.  
  1561.  
  1562. //////////////////////////////////////////////////////////////////////////////
  1563. // IPerPropertyBrowsingImpl
  1564. template <class T>
  1565. class ATL_NO_VTABLE IPerPropertyBrowsingImpl
  1566. {
  1567. public:
  1568.     // IUnknown
  1569.     //
  1570.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1571.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPerPropertyBrowsingImpl)
  1572.  
  1573.     STDMETHOD(GetDisplayString)(DISPID dispID,BSTR *pBstr)
  1574.     {
  1575.         ATLTRACE(_T("IPerPropertyBrowsingImpl::GetDisplayString\n"));
  1576.         T* pT = static_cast<T*>(this);
  1577.         CComVariant var;
  1578.         if (FAILED(CComDispatchDriver::GetProperty(pT, dispID, &var)))
  1579.         {
  1580.             *pBstr = NULL;
  1581.             return S_FALSE;
  1582.         }
  1583.  
  1584.         BSTR bstrTemp = var.bstrVal;
  1585.         if (var.vt != VT_BSTR)
  1586.         {
  1587.             CComVariant varDest;
  1588.             if (FAILED(::VariantChangeType(&varDest, &var, VARIANT_NOVALUEPROP, VT_BSTR)))
  1589.             {
  1590.                 *pBstr = NULL;
  1591.                 return S_FALSE;
  1592.             }
  1593.             bstrTemp = varDest.bstrVal;
  1594.         }
  1595.         *pBstr = SysAllocString(bstrTemp);
  1596.         return S_OK;
  1597.     }
  1598.  
  1599.     STDMETHOD(MapPropertyToPage)(DISPID dispID, CLSID *pClsid)
  1600.     {
  1601.         ATLTRACE(_T("IPerPropertyBrowsingImpl::MapPropertyToPage\n"));
  1602.         T* pT = static_cast<T*>(this);
  1603.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  1604.         _ASSERTE(pMap != NULL);
  1605.         for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  1606.         {
  1607.             if (pMap[i].szDesc == NULL)
  1608.                 continue;
  1609.             if (pMap[i].dispid == dispID)
  1610.             {
  1611.                 _ASSERTE(pMap[i].pclsidPropPage != NULL);
  1612.                 *pClsid = *(pMap[i].pclsidPropPage);
  1613.                 return S_OK;
  1614.             }
  1615.         }
  1616.         *pClsid = CLSID_NULL;
  1617.         return E_INVALIDARG;
  1618.     }
  1619.     STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut)
  1620.     {
  1621.         dispID;
  1622.         ATLTRACE(_T("IPerPropertyBrowsingImpl::GetPredefinedStrings\n"));
  1623.         if (pCaStringsOut == NULL || pCaCookiesOut == NULL)
  1624.             return E_POINTER;
  1625.  
  1626.         pCaStringsOut->cElems = 0;
  1627.         pCaStringsOut->pElems = NULL;
  1628.         pCaCookiesOut->cElems = 0;
  1629.         pCaCookiesOut->pElems = NULL;
  1630.         return S_OK;
  1631.     }
  1632.     STDMETHOD(GetPredefinedValue)(DISPID /*dispID*/, DWORD /*dwCookie*/, VARIANT* /*pVarOut*/)
  1633.     {
  1634.         ATLTRACENOTIMPL(_T("IPerPropertyBrowsingImpl::GetPredefinedValue"));
  1635.     }
  1636. };
  1637.  
  1638. //////////////////////////////////////////////////////////////////////////////
  1639. // IViewObjectExImpl
  1640. template <class T>
  1641. class ATL_NO_VTABLE IViewObjectExImpl
  1642. {
  1643. public:
  1644.     // IUnknown
  1645.     //
  1646.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1647.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IViewObjectExImpl)
  1648.  
  1649.     // IViewObject
  1650.     //
  1651.     STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  1652.                     DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  1653.                     LPCRECTL prcBounds, LPCRECTL prcWBounds,
  1654.                     BOOL (__stdcall * /*pfnContinue*/)(DWORD dwContinue),
  1655.                     DWORD /*dwContinue*/)
  1656.     {
  1657.         T* pT = static_cast<T*>(this);
  1658.         ATLTRACE(_T("IViewObjectExImpl::Draw\n"));
  1659.         return pT->IViewObject_Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw,
  1660.             prcBounds, prcWBounds);
  1661.     }
  1662.  
  1663.     STDMETHOD(GetColorSet)(DWORD /* dwDrawAspect */,LONG /* lindex */, void* /* pvAspect */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, LOGPALETTE** /* ppColorSet */)
  1664.     {
  1665.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetColorSet"));
  1666.     }
  1667.     STDMETHOD(Freeze)(DWORD /* dwDrawAspect */, LONG /* lindex */, void* /* pvAspect */,DWORD* /* pdwFreeze */)
  1668.     {
  1669.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Freeze"));
  1670.     }
  1671.     STDMETHOD(Unfreeze)(DWORD /* dwFreeze */)
  1672.     {
  1673.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Unfreeze"));
  1674.     }
  1675.     STDMETHOD(SetAdvise)(DWORD /* aspects */, DWORD /* advf */, IAdviseSink* pAdvSink)
  1676.     {
  1677.         T* pT = static_cast<T*>(this);
  1678.         ATLTRACE(_T("IViewObjectExImpl::SetAdvise\n"));
  1679.         pT->m_spAdviseSink = pAdvSink;
  1680.         return S_OK;
  1681.     }
  1682.     STDMETHOD(GetAdvise)(DWORD* /* pAspects */, DWORD* /* pAdvf */, IAdviseSink** ppAdvSink)
  1683.     {
  1684.         T* pT = static_cast<T*>(this);
  1685.         ATLTRACE(_T("IViewObjectExImpl::GetAdvise\n"));
  1686.         if (ppAdvSink != NULL)
  1687.         {
  1688.             *ppAdvSink = pT->m_spAdviseSink;
  1689.             if (pT->m_spAdviseSink)
  1690.                 pT->m_spAdviseSink->AddRef();
  1691.         }
  1692.         return S_OK;
  1693.     }
  1694.  
  1695.     // IViewObject2
  1696.     //
  1697.     STDMETHOD(GetExtent)(DWORD /* dwDrawAspect */, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel)
  1698.     {
  1699.         T* pT = static_cast<T*>(this);
  1700.         ATLTRACE(_T("IViewObjectExImpl::GetExtent\n"));
  1701.         *lpsizel = pT->m_sizeExtent;
  1702.         return S_OK;
  1703.     }
  1704.  
  1705.     // IViewObjectEx
  1706.     //
  1707.     STDMETHOD(GetRect)(DWORD /* dwAspect */, LPRECTL /* pRect */)
  1708.     {
  1709.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetRect"));
  1710.     }
  1711.     STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  1712.     {
  1713.         ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
  1714.         *pdwStatus =
  1715. //          VIEWSTATUS_DVASPECTOPAQUE | VIEWSTATUS_DVASPECTTRANSPARENT |
  1716. //          VIEWSTATUS_SOLIDBKGND |
  1717.             VIEWSTATUS_OPAQUE;
  1718.  
  1719.         return S_OK;
  1720.     }
  1721.     STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  1722.     {
  1723.         ATLTRACE(_T("IViewObjectExImpl::QueryHitPoint\n"));
  1724.         if (dwAspect == DVASPECT_CONTENT)
  1725.         {
  1726.             *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  1727.             return S_OK;
  1728.         }
  1729.         ATLTRACE(_T("Wrong DVASPECT\n"));
  1730.         return E_FAIL;
  1731.     }
  1732.     STDMETHOD(QueryHitRect)(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult)
  1733.     {
  1734.         ATLTRACE(_T("IViewObjectExImpl::QueryHitRect\n"));
  1735.         if (dwAspect == DVASPECT_CONTENT)
  1736.         {
  1737.             RECT rc;
  1738.             *pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  1739.             return S_OK;
  1740.         }
  1741.         ATLTRACE(_T("Wrong DVASPECT\n"));
  1742.         return E_FAIL;
  1743.     }
  1744.     STDMETHOD(GetNaturalExtent)(DWORD dwAspect, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, DVEXTENTINFO* pExtentInfo , LPSIZEL psizel)
  1745.     {
  1746.         T* pT = static_cast<T*>(this);
  1747.         ATLTRACE(_T("IViewObjectExImpl::GetNaturalExtent\n"));
  1748.         HRESULT hRes = E_FAIL;
  1749.         if (dwAspect == DVASPECT_CONTENT)
  1750.         {
  1751.             if (pExtentInfo->dwExtentMode == DVEXTENT_CONTENT)
  1752.             {
  1753.                 *psizel = pT->m_sizeNatural;
  1754.                 hRes = S_OK;
  1755.             }
  1756.         }
  1757.         return hRes;
  1758.     }
  1759.  
  1760. public:
  1761. };
  1762.  
  1763. //////////////////////////////////////////////////////////////////////////////
  1764. // IOleInPlaceObjectWindowlessImpl
  1765. //
  1766. template <class T>
  1767. class ATL_NO_VTABLE IOleInPlaceObjectWindowlessImpl
  1768. {
  1769. public:
  1770.     // IUnknown
  1771.     //
  1772.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1773.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceObjectWindowlessImpl)
  1774.  
  1775.     // IOleWindow
  1776.     //
  1777.  
  1778.     // Change IOleInPlaceActiveObject::GetWindow as well
  1779.     STDMETHOD(GetWindow)(HWND* phwnd)
  1780.     {
  1781.         ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::GetWindow\n"));
  1782.         T* pT = static_cast<T*>(this);
  1783.         HRESULT hRes = E_POINTER;
  1784.  
  1785.         if (pT->m_bWasOnceWindowless)
  1786.             return E_FAIL;
  1787.  
  1788.         if (phwnd != NULL)
  1789.         {
  1790.             *phwnd = pT->m_hWnd;
  1791.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  1792.         }
  1793.         return hRes;
  1794.     }
  1795.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  1796.     {
  1797.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ContextSensitiveHelp"));
  1798.     }
  1799.  
  1800.     // IOleInPlaceObject
  1801.     //
  1802.     STDMETHOD(InPlaceDeactivate)(void)
  1803.     {
  1804.         T* pT = static_cast<T*>(this);
  1805.         ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::InPlaceDeactivate\n"));
  1806.         return pT->IOleInPlaceObject_InPlaceDeactivate();
  1807.     }
  1808.     STDMETHOD(UIDeactivate)(void)
  1809.     {
  1810.         T* pT = static_cast<T*>(this);
  1811.         ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::UIDeactivate\n"));
  1812.         return pT->IOleInPlaceObject_UIDeactivate();
  1813.     }
  1814.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  1815.     {
  1816.         T* pT = static_cast<T*>(this);
  1817.         ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::SetObjectRects\n"));
  1818.         return pT->IOleInPlaceObject_SetObjectRects(prcPos, prcClip);
  1819.     }
  1820.     STDMETHOD(ReactivateAndUndo)(void)
  1821.     {
  1822.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ReactivateAndUndo"));
  1823.     }
  1824.  
  1825.     // IOleInPlaceObjectWindowless
  1826.     //
  1827.     STDMETHOD(OnWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
  1828.     {
  1829.         ATLTRACE(_T("IOleInPlaceObjectWindowlessImpl::OnWindowMessage\n"));
  1830.         T* pT = static_cast<T*>(this);
  1831.         return pT->ProcessWindowMessage(pT->m_hWnd, msg, wParam, lParam, *plResult);
  1832.     }
  1833.  
  1834.     STDMETHOD(GetDropTarget)(IDropTarget** /* ppDropTarget */)
  1835.     {
  1836.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::GetDropTarget"));
  1837.     }
  1838. };
  1839.  
  1840.  
  1841. //////////////////////////////////////////////////////////////////////////////
  1842. // IOleInPlaceActiveObjectImpl
  1843. //
  1844. template <class T>
  1845. class ATL_NO_VTABLE IOleInPlaceActiveObjectImpl
  1846. {
  1847. public:
  1848.     // IUnknown
  1849.     //
  1850.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1851.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleInPlaceActiveObjectImpl)
  1852.  
  1853.     // IOleWindow
  1854.     //
  1855.  
  1856.     // Change IOleInPlaceObjectWindowless::GetWindow as well
  1857.     STDMETHOD(GetWindow)(HWND *phwnd)
  1858.     {
  1859.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::GetWindow\n"));
  1860.         T* pT = static_cast<T*>(this);
  1861.         HRESULT hRes = E_POINTER;
  1862.  
  1863.         if (pT->m_bWasOnceWindowless)
  1864.             return E_FAIL;
  1865.  
  1866.         if (phwnd != NULL)
  1867.         {
  1868.             *phwnd = pT->m_hWnd;
  1869.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  1870.         }
  1871.         return hRes;
  1872.     }
  1873.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  1874.     {
  1875.         ATLTRACENOTIMPL(_T("IOleInPlaceActiveObjectImpl::ContextSensitiveHelp"));
  1876.     }
  1877.  
  1878.     // IOleInPlaceActiveObject
  1879.     //
  1880.     STDMETHOD(TranslateAccelerator)(LPMSG /* lpmsg */)
  1881.     {
  1882.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::TranslateAccelerator\n"));
  1883.         return E_NOTIMPL;
  1884.     }
  1885.     STDMETHOD(OnFrameWindowActivate)(BOOL /* fActivate */)
  1886.     {
  1887.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnFrameWindowActivate\n"));
  1888.         return S_OK;
  1889.     }
  1890.     STDMETHOD(OnDocWindowActivate)(BOOL /* fActivate */)
  1891.     {
  1892.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::OnDocWindowActivate\n"));
  1893.         return S_OK;
  1894.     }
  1895.     STDMETHOD(ResizeBorder)(LPCRECT /* prcBorder */, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* fFrameWindow */)
  1896.     {
  1897.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::ResizeBorder\n"));
  1898.         return S_OK;
  1899.     }
  1900.     STDMETHOD(EnableModeless)(BOOL /* fEnable */)
  1901.     {
  1902.         ATLTRACE(_T("IOleInPlaceActiveObjectImpl::EnableModeless\n"));
  1903.         return S_OK;
  1904.     }
  1905. };
  1906.  
  1907.  
  1908. //////////////////////////////////////////////////////////////////////////////
  1909. // ISpecifyPropertyPagesImpl
  1910. template <class T>
  1911. class ATL_NO_VTABLE ISpecifyPropertyPagesImpl
  1912. {
  1913. public:
  1914.     // IUnknown
  1915.     //
  1916.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1917.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(ISpecifyPropertyPagesImpl)
  1918.  
  1919.     // ISpecifyPropertyPages
  1920.     //
  1921.     STDMETHOD(GetPages)(CAUUID* pPages)
  1922.     {
  1923.         ATLTRACE(_T("ISpecifyPropertyPagesImpl::GetPages\n"));
  1924.         T* pT = static_cast<T*>(this);
  1925.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  1926.         return pT->ISpecifyPropertyPages_GetPages(pPages, pMap);
  1927.     }
  1928. };
  1929.  
  1930. //////////////////////////////////////////////////////////////////////////////
  1931. // IPointerInactiveImpl
  1932. template <class T>
  1933. class ATL_NO_VTABLE IPointerInactiveImpl
  1934. {
  1935. public:
  1936.     // IUnknown
  1937.     //
  1938.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1939.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPointerInactiveImpl)
  1940.  
  1941.     // IPointerInactive
  1942.     //
  1943.     STDMETHOD(GetActivationPolicy)(DWORD *pdwPolicy)
  1944.     {
  1945.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::GetActivationPolicy"));
  1946.     }
  1947.     STDMETHOD(OnInactiveMouseMove)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg)
  1948.     {
  1949.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveMouseMove"));
  1950.     }
  1951.     STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways)
  1952.     {
  1953.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveSetCursor"));
  1954.     }
  1955. };
  1956.  
  1957. //////////////////////////////////////////////////////////////////////////////
  1958. // IRunnableObjectImpl
  1959. template <class T>
  1960. class ATL_NO_VTABLE IRunnableObjectImpl
  1961. {
  1962. public:
  1963.     // IUnknown
  1964.     //
  1965.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  1966.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IRunnableObjectImpl)
  1967.  
  1968.     // IRunnableObject
  1969.     //
  1970.     STDMETHOD(GetRunningClass)(LPCLSID lpClsid)
  1971.     {
  1972.         ATLTRACE(_T("IRunnableObjectImpl::GetRunningClass\n"));
  1973.         T* pT = static_cast<T*>(this);
  1974.         *lpClsid = GUID_NULL;
  1975.         return E_UNEXPECTED;
  1976.     }
  1977.     STDMETHOD(Run)(LPBINDCTX)
  1978.     {
  1979.         ATLTRACE(_T("IRunnableObjectImpl::Run\n"));
  1980.         return S_OK;
  1981.     }
  1982.     virtual BOOL STDMETHODCALLTYPE IsRunning()
  1983.     {
  1984.         ATLTRACE(_T("IRunnableObjectImpl::IsRunning\n"));
  1985.         return TRUE;
  1986.     }
  1987.     STDMETHOD(LockRunning)(BOOL /*fLock*/, BOOL /*fLastUnlockCloses*/)
  1988.     {
  1989.         ATLTRACE(_T("IRunnableObjectImpl::LockRunning\n"));
  1990.         return S_OK;
  1991.     }
  1992.     STDMETHOD(SetContainedObject)(BOOL /*fContained*/)
  1993.     {
  1994.         ATLTRACE(_T("IRunnableObjectImpl::SetContainedObject\n"));
  1995.         return S_OK;
  1996.     }
  1997. };
  1998.  
  1999.  
  2000. //////////////////////////////////////////////////////////////////////////////
  2001. // IDataObjectImpl
  2002. template <class T>
  2003. class ATL_NO_VTABLE IDataObjectImpl
  2004. {
  2005. public:
  2006.     // IUnknown
  2007.     //
  2008.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  2009.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IDataObjectImpl)
  2010.  
  2011.     // IDataObject
  2012.     //
  2013.     STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  2014.     {
  2015.         ATLTRACE(_T("IDataObjectImpl::GetData\n"));
  2016.         T* pT = (T*) this;
  2017.         return pT->IDataObject_GetData(pformatetcIn, pmedium);
  2018.     }
  2019.     STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
  2020.     {
  2021.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetDataHere"));
  2022.     }
  2023.     STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  2024.     {
  2025.         ATLTRACENOTIMPL(_T("IDataObjectImpl::QueryGetData"));
  2026.     }
  2027.     STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  2028.     {
  2029.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetCanonicalFormatEtc"));
  2030.     }
  2031.     STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  2032.     {
  2033.         ATLTRACENOTIMPL(_T("IDataObjectImpl::SetData"));
  2034.     }
  2035.     STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  2036.     {
  2037.         ATLTRACENOTIMPL(_T("IDataObjectImpl::EnumFormatEtc"));
  2038.     }
  2039.     STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  2040.         DWORD *pdwConnection)
  2041.     {
  2042.         ATLTRACE(_T("IDataObjectImpl::DAdvise\n"));
  2043.         T* pT = static_cast<T*>(this);
  2044.         HRESULT hr = S_OK;
  2045.         if (pT->m_spDataAdviseHolder == NULL)
  2046.             hr = CreateDataAdviseHolder(&pT->m_spDataAdviseHolder);
  2047.  
  2048.         if (hr == S_OK)
  2049.             hr = pT->m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection);
  2050.  
  2051.         return hr;
  2052.     }
  2053.     STDMETHOD(DUnadvise)(DWORD dwConnection)
  2054.     {
  2055.         ATLTRACE(_T("IDataObjectImpl::DUnadvise\n"));
  2056.         T* pT = static_cast<T*>(this);
  2057.         HRESULT hr = S_OK;
  2058.         if (pT->m_spDataAdviseHolder == NULL)
  2059.             hr = OLE_E_NOCONNECTION;
  2060.         else
  2061.             hr = pT->m_spDataAdviseHolder->Unadvise(dwConnection);
  2062.         return hr;
  2063.     }
  2064.     STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  2065.     {
  2066.         ATLTRACE(_T("IDataObjectImpl::EnumDAdvise\n"));
  2067.         T* pT = static_cast<T*>(this);
  2068.         HRESULT hr = E_FAIL;
  2069.         if (pT->m_spDataAdviseHolder != NULL)
  2070.             hr = pT->m_spDataAdviseHolder->EnumAdvise(ppenumAdvise);
  2071.         return hr;
  2072.     }
  2073. };
  2074.  
  2075. //////////////////////////////////////////////////////////////////////////////
  2076. // IPropertyNotifySinkCP
  2077. template <class T, class CDV = CComDynamicUnkArray >
  2078. class ATL_NO_VTABLE IPropertyNotifySinkCP :
  2079.     public IConnectionPointImpl<T, &IID_IPropertyNotifySink, CDV>
  2080. {
  2081. public:
  2082.     typedef CFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  2083. };
  2084.  
  2085.  
  2086. //////////////////////////////////////////////////////////////////////////////
  2087. // IObjectSafety
  2088. //
  2089.  
  2090. template <class T>
  2091. class ATL_NO_VTABLE IObjectSafetyImpl
  2092. {
  2093. public:
  2094.     IObjectSafetyImpl()
  2095.     {
  2096.         m_dwSafety = 0;
  2097.     }
  2098.  
  2099.     // IUnknown
  2100.     //
  2101.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  2102.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IObjectSafetyImpl)
  2103.  
  2104.     // IObjectSafety
  2105.     //
  2106.     STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  2107.     {
  2108.         ATLTRACE(_T("IObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
  2109.         if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
  2110.             return E_POINTER;
  2111.         HRESULT hr = S_OK;
  2112.         if (riid == IID_IDispatch)
  2113.         {
  2114.             *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  2115.             *pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER;
  2116.         }
  2117.         else
  2118.         {
  2119.             *pdwSupportedOptions = 0;
  2120.             *pdwEnabledOptions = 0;
  2121.             hr = E_NOINTERFACE;
  2122.         }
  2123.         return hr;
  2124.     }
  2125.     STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  2126.     {
  2127.         ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
  2128.         // If we're being asked to set our safe for scripting option then oblige
  2129.         if (riid == IID_IDispatch)
  2130.         {
  2131.             // Store our current safety level to return in GetInterfaceSafetyOptions
  2132.             m_dwSafety = dwEnabledOptions & dwOptionSetMask;
  2133.             return S_OK;
  2134.         }
  2135.         return E_NOINTERFACE;
  2136.     }
  2137.  
  2138.     DWORD m_dwSafety;
  2139. };
  2140.  
  2141.  
  2142. template <class T>
  2143. class ATL_NO_VTABLE IOleLinkImpl
  2144. {
  2145.     // IUnknown
  2146.     //
  2147.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  2148.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IOleLinkImpl)
  2149.  
  2150.     STDMETHOD(SetUpdateOptions)(DWORD /* dwUpdateOpt */)
  2151.     {
  2152.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetUpdateOptions"));
  2153.     }
  2154.  
  2155.     STDMETHOD(GetUpdateOptions)(DWORD* /* pdwUpdateOpt */)
  2156.     {
  2157.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetUpdateOptions"));
  2158.     }
  2159.  
  2160.     STDMETHOD(SetSourceMoniker)(IMoniker* /* pmk */, REFCLSID /* rclsid */)
  2161.     {
  2162.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceMoniker"));
  2163.     }
  2164.  
  2165.     STDMETHOD(GetSourceMoniker)(IMoniker** /* ppmk */)
  2166.     {
  2167.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetSourceMoniker"));
  2168.     };
  2169.  
  2170.     STDMETHOD(SetSourceDisplayName)(LPCOLESTR /* pszStatusText */)
  2171.     {
  2172.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceDisplayName"));
  2173.     }
  2174.  
  2175.     STDMETHOD(GetSourceDisplayName)(LPOLESTR *ppszDisplayName)
  2176.     {
  2177.         ATLTRACE(_T("IOleLink::GetSourceDisplayName\n"));
  2178.         *ppszDisplayName = NULL;
  2179.         return E_FAIL;
  2180.     }
  2181.  
  2182.     STDMETHOD(BindToSource)(DWORD /* bindflags */, IBindCtx* /* pbc */)
  2183.     {
  2184.         ATLTRACENOTIMPL(_T("IOleLinkImpl::BindToSource\n"));
  2185.     };
  2186.  
  2187.     STDMETHOD(BindIfRunning)()
  2188.     {
  2189.         ATLTRACE(_T("IOleLinkImpl::BindIfRunning\n"));
  2190.         return S_OK;
  2191.     };
  2192.  
  2193.     STDMETHOD(GetBoundSource)(IUnknown** /* ppunk */)
  2194.     {
  2195.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetBoundSource"));
  2196.     };
  2197.  
  2198.     STDMETHOD(UnbindSource)()
  2199.     {
  2200.         ATLTRACENOTIMPL(_T("IOleLinkImpl::UnbindSource"));
  2201.     };
  2202.  
  2203.     STDMETHOD(Update)(IBindCtx* /* pbc */)
  2204.     {
  2205.         ATLTRACENOTIMPL(_T("IOleLinkImpl::Update"));
  2206.     };
  2207. };
  2208.  
  2209.  
  2210. template <class T>
  2211. class ATL_NO_VTABLE IBindStatusCallbackImpl
  2212. {
  2213. public:
  2214.     // IUnknown
  2215.     //
  2216.     STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  2217.     _ATL_DEBUG_ADDREF_RELEASE_IMPL(IBindStatusCallbackImpl)
  2218.  
  2219.     // IBindStatusCallback
  2220.     //
  2221.     STDMETHOD(OnStartBinding)(DWORD /* dwReserved */, IBinding *pBinding)
  2222.     {
  2223.         ATLTRACE(_T("IBindStatusCallbackImpl::OnStartBinding\n"));
  2224.         return S_OK;
  2225.     }
  2226.  
  2227.     STDMETHOD(GetPriority)(LONG* /* pnPriority */)
  2228.     {
  2229.         ATLTRACENOTIMPL(_T("IBindStatusCallbackImpl::GetPriority"));
  2230.     }
  2231.  
  2232.     STDMETHOD(OnLowResource)(DWORD /* reserved */)
  2233.     {
  2234.         ATLTRACE(_T("IBindStatusCallbackImpl::OnLowResource\n"));
  2235.         return S_OK;
  2236.     }
  2237.  
  2238.     STDMETHOD(OnProgress)(ULONG /* ulProgress */, ULONG /* ulProgressMax */, ULONG /* ulStatusCode */, LPCWSTR /* szStatusText */)
  2239.     {
  2240.         ATLTRACE(_T("IBindStatusCallbackImpl::OnProgress\n"));
  2241.         return S_OK;
  2242.     }
  2243.  
  2244.     STDMETHOD(OnStopBinding)(HRESULT /* hresult */, LPCWSTR /* szError */)
  2245.     {
  2246.         ATLTRACE(_T("IBindStatusCallbackImpl::OnStopBinding\n"));
  2247.         return S_OK;
  2248.     }
  2249.  
  2250.     STDMETHOD(GetBindInfo)(DWORD* /* pgrfBINDF */, BINDINFO* /* pBindInfo */)
  2251.     {
  2252.         ATLTRACE(_T("IBindStatusCallbackImpl::GetBindInfo\n"));
  2253.         return S_OK;
  2254.     }
  2255.  
  2256.     STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  2257.     {
  2258.         ATLTRACE(_T("IBindStatusCallbackImpl::OnDataAvailable\n"));
  2259.         return S_OK;
  2260.     }
  2261.  
  2262.     STDMETHOD(OnObjectAvailable)(REFIID /* riid */, IUnknown* /* punk */)
  2263.     {
  2264.         ATLTRACE(_T("IBindStatusCallbackImpl::OnObjectAvailable\n"));
  2265.         return S_OK;
  2266.     }
  2267. };
  2268.  
  2269.  
  2270. template <class T>
  2271. class ATL_NO_VTABLE CBindStatusCallback :
  2272.     public CComObjectRootEx<T::_ThreadModel::ThreadModelNoCS>,
  2273.     public IBindStatusCallbackImpl<T>
  2274. {
  2275.     typedef void (T::*ATL_PDATAAVAILABLE)(CBindStatusCallback<T>* pbsc, BYTE* pBytes, DWORD dwSize);
  2276.  
  2277. public:
  2278.  
  2279. BEGIN_COM_MAP(CBindStatusCallback<T>)
  2280.     COM_INTERFACE_ENTRY_IID(IID_IBindStatusCallback, IBindStatusCallbackImpl<T>)
  2281. END_COM_MAP()
  2282.  
  2283.  
  2284.     CBindStatusCallback()
  2285.     {
  2286.         m_pT = NULL;
  2287.         m_pFunc = NULL;
  2288.     }
  2289.     ~CBindStatusCallback()
  2290.     {
  2291.         ATLTRACE(_T("~CBindStatusCallback\n"));
  2292.     }
  2293.  
  2294.     STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pBinding)
  2295.     {
  2296.         ATLTRACE(_T("CBindStatusCallback::OnStartBinding\n"));
  2297.         m_spBinding = pBinding;
  2298.         return S_OK;
  2299.     }
  2300.  
  2301.     STDMETHOD(GetPriority)(LONG *pnPriority)
  2302.     {
  2303.         ATLTRACENOTIMPL(_T("CBindStatusCallback::GetPriority"));
  2304.     }
  2305.  
  2306.     STDMETHOD(OnLowResource)(DWORD reserved)
  2307.     {
  2308.         ATLTRACENOTIMPL(_T("CBindStatusCallback::OnLowResource"));
  2309.     }
  2310.  
  2311.     STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  2312.     {
  2313.         ATLTRACENOTIMPL(_T("CBindStatusCallback::OnProgress"));
  2314.     }
  2315.  
  2316.     STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError)
  2317.     {
  2318.         ATLTRACE(_T("CBindStatusCallback::OnStopBinding\n"));
  2319.         m_spBinding.Release();
  2320.         return S_OK;
  2321.     }
  2322.  
  2323.     STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo)
  2324.     {
  2325.         ATLTRACE(_T("CBindStatusCallback::GetBindInfo\n"));
  2326.         *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
  2327.             BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;
  2328.         pbindInfo->cbSize = sizeof(BINDINFO);
  2329.         pbindInfo->szExtraInfo = NULL;
  2330.         memset(&pbindInfo->stgmedData, 0, sizeof(STGMEDIUM));
  2331.         pbindInfo->grfBindInfoF = 0;
  2332.         pbindInfo->dwBindVerb = BINDVERB_GET;
  2333.         pbindInfo->szCustomVerb = NULL;
  2334.         return S_OK;
  2335.     }
  2336.  
  2337.     STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  2338.     {
  2339.         ATLTRACE(_T("CBindStatusCallback::OnDataAvailable\n"));
  2340.         HRESULT hr = S_OK;
  2341.  
  2342.         // Get the Stream passed
  2343.         if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
  2344.         {
  2345.             if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM)
  2346.             {
  2347.                 m_spStream = pstgmed->pstm;
  2348.                 if (m_spStream)
  2349.                     m_spStream->AddRef();
  2350.             }
  2351.         }
  2352.  
  2353.         DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read
  2354.         DWORD dwActuallyRead = 0;            // Placeholder for amount read during this pull
  2355.  
  2356.         // If there is some data to be read then go ahead and read them
  2357.         if (m_spStream)
  2358.         {
  2359.             if (dwRead > 0)
  2360.             {
  2361.                 BYTE* pBytes = NULL;
  2362.                 ATLTRY(pBytes = new BYTE[dwRead + 1]);
  2363.                 if (pBytes == NULL)
  2364.                     return S_FALSE;
  2365.                 hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead);
  2366.                 if (SUCCEEDED(hr))
  2367.                 {
  2368.                     pBytes[dwActuallyRead] = 0;
  2369.                     if (dwActuallyRead>0)
  2370.                     {
  2371.                         (m_pT->*m_pFunc)(this, pBytes, dwActuallyRead);
  2372.                         m_dwTotalRead += dwActuallyRead;
  2373.                     }
  2374.                 }
  2375.                 delete[] pBytes;
  2376.             }
  2377.         }
  2378.  
  2379.         if (BSCF_LASTDATANOTIFICATION & grfBSCF)
  2380.             m_spStream.Release();
  2381.         return hr;
  2382.     }
  2383.  
  2384.     STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk)
  2385.     {
  2386.         ATLTRACENOTIMPL(_T("CBindStatusCallback::OnObjectAvailable"));
  2387.     }
  2388.  
  2389.     HRESULT _StartAsyncDownload(BSTR bstrURL, IUnknown* pUnkContainer, BOOL bRelative)
  2390.     {
  2391.         m_dwTotalRead = 0;
  2392.         m_dwAvailableToRead = 0;
  2393.         HRESULT hr = S_OK;
  2394.         CComQIPtr<IServiceProvider, &IID_IServiceProvider> spServiceProvider(pUnkContainer);
  2395.         CComPtr<IBindHost> spBindHost;
  2396.         if (spServiceProvider)
  2397.             spServiceProvider->QueryService(SID_IBindHost, IID_IBindHost, (void**)&spBindHost);
  2398.  
  2399.         if (spBindHost == NULL)
  2400.         {
  2401.             if (bRelative)
  2402.                 return E_NOINTERFACE;  // relative asked for, but no IBindHost
  2403.             hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  2404.             if (SUCCEEDED(hr))
  2405.                 hr = CreateBindCtx(0, &m_spBindCtx);
  2406.  
  2407.             if (SUCCEEDED(hr))
  2408.                 hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), 0, 0L);
  2409.             else
  2410.                 m_spMoniker.Release();
  2411.  
  2412.             if (SUCCEEDED(hr))
  2413.             {
  2414.                 IStream* pStream;
  2415.                 hr = m_spMoniker->BindToStorage(m_spBindCtx, 0, IID_IStream, (void**)&pStream);
  2416.             }
  2417.         }
  2418.         else
  2419.         {
  2420.             hr = CreateBindCtx(0, &m_spBindCtx);
  2421.             if (SUCCEEDED(hr))
  2422.                 hr = RegisterBindStatusCallback(m_spBindCtx, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), 0, 0L);
  2423.  
  2424.             if (SUCCEEDED(hr))
  2425.             {
  2426.                 if (bRelative)
  2427.                     hr = spBindHost->CreateMoniker(bstrURL, m_spBindCtx, &m_spMoniker, 0);
  2428.                 else
  2429.                     hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  2430.             }
  2431.  
  2432.             if (SUCCEEDED(hr))
  2433.             {
  2434.                 IStream* pStream;
  2435.                 hr = spBindHost->MonikerBindToStorage(m_spMoniker, NULL, reinterpret_cast<IBindStatusCallback*>(static_cast<IBindStatusCallbackImpl<T>*>(this)), IID_IStream, (void**)&pStream);
  2436.                 ATLTRACE(_T("Bound"));
  2437.             }
  2438.         }
  2439.         return hr;
  2440.     }
  2441.  
  2442.     HRESULT StartAsyncDownload(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  2443.     {
  2444.         m_pT = pT;
  2445.         m_pFunc = pFunc;
  2446.         return  _StartAsyncDownload(bstrURL, pUnkContainer, bRelative);
  2447.     }
  2448.  
  2449.     static HRESULT Download(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  2450.     {
  2451.         CComObject<CBindStatusCallback<T> > *pbsc;
  2452.         HRESULT hRes = CComObject<CBindStatusCallback<T> >::CreateInstance(&pbsc);
  2453.         if (FAILED(hRes))
  2454.             return hRes;
  2455.         return pbsc->StartAsyncDownload(pT, pFunc, bstrURL, pUnkContainer, bRelative);
  2456.     }
  2457.  
  2458.     CComPtr<IMoniker> m_spMoniker;
  2459.     CComPtr<IBindCtx> m_spBindCtx;
  2460.     CComPtr<IBinding> m_spBinding;
  2461.     CComPtr<IStream> m_spStream;
  2462.     T* m_pT;
  2463.     ATL_PDATAAVAILABLE m_pFunc;
  2464.     DWORD m_dwTotalRead;
  2465.     DWORD m_dwAvailableToRead;
  2466. };
  2467.  
  2468. #define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \
  2469.     HRESULT STDMETHODCALLTYPE put_##fname(type pname) \
  2470.     { \
  2471.         T* pT = (T*) this; \
  2472.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2473.             return S_FALSE; \
  2474.         pT->m_##pname = pname; \
  2475.         pT->m_bRequiresSave = TRUE; \
  2476.         pT->FireOnChanged(dispid); \
  2477.         pT->FireViewChange(); \
  2478.         return S_OK; \
  2479.     } \
  2480.     HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \
  2481.     { \
  2482.         T* pT = (T*) this; \
  2483.         *p##pname = pT->m_##pname; \
  2484.         return S_OK; \
  2485.     }
  2486.  
  2487. #define IMPLEMENT_BOOL_STOCKPROP(fname, pname, dispid) \
  2488.     HRESULT STDMETHODCALLTYPE put_##fname(VARIANT_BOOL pname) \
  2489.     { \
  2490.         T* pT = (T*) this; \
  2491.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2492.             return S_FALSE; \
  2493.         pT->m_##pname = pname; \
  2494.         pT->m_bRequiresSave = TRUE; \
  2495.         pT->FireOnChanged(dispid); \
  2496.         pT->FireViewChange(); \
  2497.         return S_OK; \
  2498.     } \
  2499.     HRESULT STDMETHODCALLTYPE get_##fname(VARIANT_BOOL* p##pname) \
  2500.     { \
  2501.         T* pT = (T*) this; \
  2502.         *p##pname = pT->m_##pname ? VARIANT_TRUE : VARIANT_FALSE; \
  2503.         return S_OK; \
  2504.     }
  2505.  
  2506. #define IMPLEMENT_BSTR_STOCKPROP(fname, pname, dispid) \
  2507.     HRESULT STDMETHODCALLTYPE put_##fname(BSTR pname) \
  2508.     { \
  2509.         T* pT = (T*) this; \
  2510.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  2511.             return S_FALSE; \
  2512.         *(&(pT->m_##pname)) = SysAllocString(pname); \
  2513.         pT->m_bRequiresSave = TRUE; \
  2514.         pT->FireOnChanged(dispid); \
  2515.         pT->FireViewChange(); \
  2516.         return S_OK; \
  2517.     } \
  2518.     HRESULT STDMETHODCALLTYPE get_##fname(BSTR* p##pname) \
  2519.     { \
  2520.         T* pT = (T*) this; \
  2521.         *p##pname = SysAllocString(pT->m_##pname); \
  2522.         return S_OK; \
  2523.     }
  2524.  
  2525. template < class T, class InterfaceName, const IID* piid, const GUID* plibid>
  2526. class ATL_NO_VTABLE CStockPropImpl : public IDispatchImpl< InterfaceName, piid, plibid >
  2527. {
  2528. public:
  2529.     // Font
  2530.     HRESULT STDMETHODCALLTYPE put_Font(IFontDisp* pFont)
  2531.     {
  2532.         T* pT = (T*) this;
  2533.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  2534.             return S_FALSE;
  2535.         pT->m_pFont = 0;
  2536.         if (pFont)
  2537.         {
  2538.             CComQIPtr<IFont, &IID_IFont> p(pFont);
  2539.             if (p)
  2540.             {
  2541.                 CComPtr<IFont> pFont;
  2542.                 p->Clone(&pFont);
  2543.                 if (pFont)
  2544.                     pFont->QueryInterface(IID_IFontDisp, (void**) &pT->m_pFont);
  2545.             }
  2546.         }
  2547.         pT->m_bRequiresSave = TRUE;
  2548.         pT->FireOnChanged(DISPID_FONT);
  2549.         pT->FireViewChange();
  2550.         return S_OK;
  2551.     }
  2552.     HRESULT STDMETHODCALLTYPE putref_Font(IFontDisp* pFont)
  2553.     {
  2554.         T* pT = (T*) this;
  2555.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  2556.             return S_FALSE;
  2557.         pT->m_pFont = pFont;
  2558.         pT->m_bRequiresSave = TRUE;
  2559.         pT->FireOnChanged(DISPID_FONT);
  2560.         pT->FireViewChange();
  2561.         return S_OK;
  2562.     }
  2563.     HRESULT STDMETHODCALLTYPE get_Font(IFontDisp** ppFont)
  2564.     {
  2565.         T* pT = (T*) this;
  2566.         *ppFont = pT->m_pFont;
  2567.         if (*ppFont != NULL)
  2568.             (*ppFont)->AddRef();
  2569.         return S_OK;
  2570.     }
  2571.     // Picture
  2572.     HRESULT STDMETHODCALLTYPE put_Picture(IPictureDisp* pPicture)
  2573.     {
  2574.         T* pT = (T*) this;
  2575.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  2576.             return S_FALSE;
  2577.         pT->m_pPicture = 0;
  2578.         if (pPicture)
  2579.         {
  2580.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  2581.             if (p)
  2582.             {
  2583.                 ULARGE_INTEGER l;
  2584.                 p->GetSizeMax(&l);
  2585.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  2586.                 if (hGlob)
  2587.                 {
  2588.                     CComPtr<IStream> spStream;
  2589.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  2590.                     if (spStream)
  2591.                     {
  2592.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  2593.                         {
  2594.                             LARGE_INTEGER l;
  2595.                             l.QuadPart = 0;
  2596.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  2597.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pPicture);
  2598.                         }
  2599.                         spStream.Release();
  2600.                     }
  2601.                     GlobalFree(hGlob);
  2602.                 }
  2603.             }
  2604.         }
  2605.         pT->m_bRequiresSave = TRUE;
  2606.         pT->FireOnChanged(DISPID_PICTURE);
  2607.         pT->FireViewChange();
  2608.         return S_OK;
  2609.     }
  2610.     HRESULT STDMETHODCALLTYPE putref_Picture(IPictureDisp* pPicture)
  2611.     {
  2612.         T* pT = (T*) this;
  2613.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  2614.             return S_FALSE;
  2615.         pT->m_pPicture = pPicture;
  2616.         pT->m_bRequiresSave = TRUE;
  2617.         pT->FireOnChanged(DISPID_PICTURE);
  2618.         pT->FireViewChange();
  2619.         return S_OK;
  2620.     }
  2621.     HRESULT STDMETHODCALLTYPE get_Picture(IPictureDisp** ppPicture)
  2622.     {
  2623.         T* pT = (T*) this;
  2624.         *ppPicture = pT->m_pPicture;
  2625.         if (*ppPicture != NULL)
  2626.             (*ppPicture)->AddRef();
  2627.         return S_OK;
  2628.     }
  2629.     // MouseIcon
  2630.     HRESULT STDMETHODCALLTYPE put_MouseIcon(IPictureDisp* pPicture)
  2631.     {
  2632.         T* pT = (T*) this;
  2633.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  2634.             return S_FALSE;
  2635.         pT->m_pMouseIcon = 0;
  2636.         if (pPicture)
  2637.         {
  2638.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  2639.             if (p)
  2640.             {
  2641.                 ULARGE_INTEGER l;
  2642.                 p->GetSizeMax(&l);
  2643.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  2644.                 if (hGlob)
  2645.                 {
  2646.                     CComPtr<IStream> spStream;
  2647.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  2648.                     if (spStream)
  2649.                     {
  2650.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  2651.                         {
  2652.                             LARGE_INTEGER l;
  2653.                             l.QuadPart = 0;
  2654.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  2655.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pMouseIcon);
  2656.                         }
  2657.                         spStream.Release();
  2658.                     }
  2659.                     GlobalFree(hGlob);
  2660.                 }
  2661.             }
  2662.         }
  2663.         pT->m_bRequiresSave = TRUE;
  2664.         pT->FireOnChanged(DISPID_MOUSEICON);
  2665.         pT->FireViewChange();
  2666.         return S_OK;
  2667.     }
  2668.     HRESULT STDMETHODCALLTYPE putref_MouseIcon(IPictureDisp* pPicture)
  2669.     {
  2670.         T* pT = (T*) this;
  2671.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  2672.             return S_FALSE;
  2673.         pT->m_pMouseIcon = pPicture;
  2674.         pT->m_bRequiresSave = TRUE;
  2675.         pT->FireOnChanged(DISPID_MOUSEICON);
  2676.         pT->FireViewChange();
  2677.         return S_OK;
  2678.     }
  2679.     HRESULT STDMETHODCALLTYPE get_MouseIcon(IPictureDisp** ppPicture)
  2680.     {
  2681.         T* pT = (T*) this;
  2682.         *ppPicture = pT->m_pMouseIcon;
  2683.         if (*ppPicture != NULL)
  2684.             (*ppPicture)->AddRef();
  2685.         return S_OK;
  2686.     }
  2687.     IMPLEMENT_STOCKPROP(OLE_COLOR, BackColor, clrBackColor, DISPID_BACKCOLOR)
  2688.     IMPLEMENT_STOCKPROP(OLE_COLOR, BorderColor, clrBorderColor, DISPID_BORDERCOLOR)
  2689.     IMPLEMENT_STOCKPROP(OLE_COLOR, FillColor, clrFillColor, DISPID_FILLCOLOR)
  2690.     IMPLEMENT_STOCKPROP(OLE_COLOR, ForeColor, clrForeColor, DISPID_FORECOLOR)
  2691.     IMPLEMENT_BOOL_STOCKPROP(AutoSize, bAutoSize, DISPID_AUTOSIZE)
  2692.     IMPLEMENT_BOOL_STOCKPROP(Valid, bValid, DISPID_VALID)
  2693.     IMPLEMENT_BOOL_STOCKPROP(Enabled, bEnabled, DISPID_ENABLED)
  2694.     IMPLEMENT_BOOL_STOCKPROP(TabStop, bTabStop, DISPID_TABSTOP)
  2695.     IMPLEMENT_BOOL_STOCKPROP(BorderVisible, bBorderVisible, DISPID_BORDERVISIBLE)
  2696.     IMPLEMENT_BSTR_STOCKPROP(Text, bstrText, DISPID_TEXT)
  2697.     IMPLEMENT_BSTR_STOCKPROP(Caption, bstrCaption, DISPID_CAPTION)
  2698.     HRESULT STDMETHODCALLTYPE put_Window(long /*hWnd*/)
  2699.     {
  2700.         return E_FAIL;
  2701.     }
  2702.     HRESULT STDMETHODCALLTYPE get_Window(long* phWnd)
  2703.     {
  2704.         T* pT = (T*) this;
  2705.         *phWnd = (long)pT->m_hWnd;
  2706.         return S_OK;
  2707.     }
  2708.     IMPLEMENT_STOCKPROP(long, BackStyle, nBackStyle, DISPID_BACKSTYLE)
  2709.     IMPLEMENT_STOCKPROP(long, BorderStyle, nBorderStyle, DISPID_BORDERSTYLE)
  2710.     IMPLEMENT_STOCKPROP(long, BorderWidth, nBorderWidth, DISPID_BORDERWIDTH)
  2711.     IMPLEMENT_STOCKPROP(long, DrawMode, nDrawMode, DISPID_DRAWMODE)
  2712.     IMPLEMENT_STOCKPROP(long, DrawStyle, nDrawStyle, DISPID_DRAWSTYLE)
  2713.     IMPLEMENT_STOCKPROP(long, DrawWidth, nDrawWidth, DISPID_DRAWWIDTH)
  2714.     IMPLEMENT_STOCKPROP(long, FillStyle, nFillStyle, DISPID_FILLSTYLE)
  2715.     IMPLEMENT_STOCKPROP(long, Appearance, nAppearance, DISPID_APPEARANCE)
  2716.     IMPLEMENT_STOCKPROP(long, MousePointer, nMousePointer, DISPID_MOUSEPOINTER)
  2717.     IMPLEMENT_STOCKPROP(long, ReadyState, nReadyState, DISPID_READYSTATE)
  2718. };
  2719.  
  2720. #if defined(BCC32_COMPAT)
  2721. // Missing pop causes misalignment of VCL headers.
  2722. #pragma pack(pop)
  2723. #endif
  2724.  
  2725. #ifndef ATL_NO_NAMESPACE
  2726. }; //namespace ATL
  2727. #endif
  2728.  
  2729.  
  2730. #endif // __ATLCTL_H__
  2731.  
  2732.